在WHERE子句中使用mysql SUM()
假设我有这张桌子
id | cash 1 200 2 301 3 101 4 700
我想要返回所有以前的现金总和大于某个值的第一行:
例如,如果我想返回所有以前的现金的总和大于500的第一行,则返回到第3行
我如何使用mysql语句来做到这一点?
使用WHERE SUM(cash) > 500
不起作用
您只能在HAVING子句中使用聚合进行比较:
GROUP BY ... HAVING SUM(cash) > 500
HAVING
子句要求您定义一个GROUP BY子句。
要获得所有以前的现金总和大于某个值的第一行,请使用:
SELECT y.id, y.cash FROM (SELECT t.id, t.cash, (SELECT SUM(x.cash) FROM TABLE x WHERE x.id <= t.id) AS running_total FROM TABLE t ORDER BY t.id) y WHERE y.running_total > 500 ORDER BY y.id LIMIT 1
因为聚合函数发生在子查询中,所以它的列别名可以在WHERE子句中引用。
没有testing,但我认为这将是接近?
SELECT m1.id FROM mytable m1 INNER JOIN mytable m2 ON m1.id < m2.id GROUP BY m1.id HAVING SUM(m1.cash) > 500 ORDER BY m1.id LIMIT 1,2
这个想法是把所有以前的行求和,只得到前面的行总和> 500的那个,然后跳过一个返回下一个。
通常,SQL查询的WHERE
子句中的条件只能引用单个行。 任何订单由ORDER BY
子句定义之前,对WHERE
子句的上下文进行求值,并且RDBMS表不存在任何隐式顺序。
您可以使用派生表将每行连接到具有较小id
值的行组,并生成每个sum组的总和。 然后testing总和符合您的标准。
CREATE TABLE MyTable ( id INT PRIMARY KEY, cash INT ); INSERT INTO MyTable (id, cash) VALUES (1, 200), (2, 301), (3, 101), (4, 700); SELECT s.* FROM ( SELECT t.id, SUM(prev.cash) AS cash_sum FROM MyTable t JOIN MyTable prev ON (t.id > prev.id) GROUP BY t.id) AS s WHERE s.cash_sum >= 500 ORDER BY s.id LIMIT 1;
输出:
+----+----------+ | id | cash_sum | +----+----------+ | 3 | 501 | +----+----------+
当使用集合函数进行筛选时,您必须使用HAVING语句。
SELECT * FROM tblMoney HAVING Sum(CASH) > 500