используйте mysql SUM () в предложении WHERE

36

Предположим, что у меня есть эта таблица

id | cash 
1    200
2    301
3    101
4    700

и я хочу вернуть первую строку, в которой сумма всех предыдущих денежных средств превышает определенное значение:

Так, например, если я хочу вернуть первую строку, в которой сумма всех предыдущих денежных средств превышает 500, следует вернуться к строке 3

Как это сделать с помощью инструкции mysql?

используя WHERE SUM(cash) > 500 не работает

  • 1
    Вы хотите выбрать id=3 потому что 200 + 300 >= 500 или потому что 501 > 500 ?
  • 0
    Включаете ли вы предложение ORDER BY? Вы не можете сказать, получить «следующую» запись, потому что строки не хранятся в определенном порядке.
Показать ещё 1 комментарий
Теги:
aggregate-functions

4 ответа

73
Лучший ответ

Вы можете использовать агрегаты только для сравнения в предложении 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.

  • 0
    Я думаю, что его редакция прояснила, что он имел в виду и сделал это больше не верно
  • 0
    @Michael Mrozek: Спасибо за голову, думаю, я понял.
Показать ещё 3 комментария
5

Не проверено, но я думаю, что это будет близко?

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, затем пропустить одну и вернуть следующую.

  • 0
    Это не работает, так как возвращает 2. Использование SELECT m2.id вместо SELECT m1.id возвращает 3 - ожидаемый результат. Но что, если id не в порядке. Следует ли использовать ORDER BY m2.id вместо ORDER BY m1.id ? Но предложение ORDER BY делает упорядочивание при отображении вывода, верно? Итак, можете ли вы объяснить, как id могут быть отсортированы в порядке ASC , когда работает отношение JOIN вместо представления результата?
3

В общем случае условие в выражении 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 |
+----+----------+
  • 0
    показывает ошибку: «# 1052 - Столбец« наличные »в списке полей неоднозначен»
  • 0
    @IstiaqueAhmed, спасибо, что поймали это. Я добавил имя корреляции, так что теперь это SUM(prev.cash) . Это должно исправить ошибку.
Показать ещё 6 комментариев
0

При использовании агрегатных функций для фильтрации вы должны использовать оператор HAVING.

SELECT *
FROM tblMoney
HAVING Sum(CASH) > 500

Ещё вопросы

Сообщество Overcoder
Наверх
Меню