Предположим, что у меня есть эта таблица
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, затем пропустить одну и вернуть следующую.
SELECT m2.id
вместо SELECT m1.id
возвращает 3 - ожидаемый результат. Но что, если id
не в порядке. Следует ли использовать ORDER BY m2.id
вместо ORDER BY m1.id
? Но предложение ORDER BY
делает упорядочивание при отображении вывода, верно? Итак, можете ли вы объяснить, как id
могут быть отсортированы в порядке ASC
, когда работает отношение JOIN
вместо представления результата?
В общем случае условие в выражении WHERE
SQL-запроса может ссылаться только на одну строку. Контекст предложения WHERE
оценивается до того, как какой-либо порядок был определен в предложении ORDER BY
, и нет никакого неявного порядка для таблицы РСУБД.
Вы можете использовать производную таблицу для объединения каждой строки в группу строк с меньшим значением 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 |
+----+----------+
SUM(prev.cash)
. Это должно исправить ошибку.
При использовании агрегатных функций для фильтрации вы должны использовать оператор HAVING.
SELECT *
FROM tblMoney
HAVING Sum(CASH) > 500
id=3
потому что200 + 300 >= 500
или потому что501 > 500
?