suppose que j’ai cette table
id | cash 1 200 2 301 3 101 4 700
et je veux retourner la première ligne dans laquelle la sum de toutes les espèces précédentes est supérieure à une certaine valeur:
Donc, par exemple, si je veux retourner la première ligne dans laquelle la sum de toutes les espèces précédentes est supérieure à 500, il faut retourner à la ligne 3
Comment puis-je le faire en utilisant l’instruction mysql?
utiliser WHERE SUM(cash) > 500
ne fonctionne pas
Vous ne pouvez utiliser des agrégats que pour la comparaison dans la clause HAVING:
GROUP BY ... HAVING SUM(cash) > 500
La clause HAVING
vous oblige à définir une clause GROUP BY.
Pour obtenir la première ligne où la sum de toutes les espèces précédentes est supérieure à une certaine valeur, utilisez:
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
Comme la fonction d’agrégat se produit dans une sous-requête, l’alias de colonne correspondant peut être référencé dans la clause WHERE.
Non testé, mais je pense que ce sera proche?
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
L’idée est de résumer toutes les lignes précédentes, d’obtenir seulement celles où la sum des lignes précédentes est> 500, puis d’en ignorer une et de renvoyer la suivante.
En général, une condition dans la clause WHERE
d’une requête SQL ne peut référencer qu’une seule ligne. Le contexte d’une clause WHERE
est évalué avant qu’un ordre ait été défini par une clause ORDER BY
et il n’y a pas d’ordre implicite vers une table de SGBDR.
Vous pouvez utiliser une table dérivée pour joindre chaque ligne au groupe de lignes avec une valeur d’ id
inférieure et produire la sum de chaque groupe de sum. Ensuite, testez où la sum répond à votre critère.
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;
Sortie:
+----+----------+ | id | cash_sum | +----+----------+ | 3 | 501 | +----+----------+
Lorsque vous utilisez des fonctions d’agrégation pour filtrer, vous devez utiliser une instruction HAVING.
SELECT * FROM tblMoney HAVING Sum(CASH) > 500