假设我有这张桌子
id | cash
1 200
2 301
3 101
4 700
我想返回所有先前现金的总和大于某个值的第一行:
因此,例如,如果我想返回所有先前现金的总和大于 500 的第一行,则应该返回第 3 行
如何使用 mysql 语句执行此操作?
使用WHERE SUM(cash) > 500
不起作用
假设我有这张桌子
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 子句中引用它的列别名。
未经测试,但我认为这将接近?
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 的行,然后跳过一个并返回下一个。
通常,WHERE
SQL 查询子句中的条件只能引用单行。子句的上下文在WHERE
子句定义任何顺序之前进行评估ORDER BY
,并且 RDBMS 表没有隐式顺序。
您可以使用派生表将每一行连接到具有较小id
值的行组,并生成每个总和组的总和。然后测试总和符合您的标准。
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