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 somme de tout l'argent précédent est supérieure à une certaine valeur:
Ainsi, par exemple, si je veux retourner la première ligne dans laquelle la somme de tout l'argent précédent est supérieur à 500, il faut retourner à la ligne 3
Comment puis-je faire cela en utilisant la déclaration mysql?
l'utilisation de WHERE SUM(cash) > 500
ne fonctionne pas
Vous pouvez uniquement utiliser des agrégats à des fins de comparaison dans la clause HAVING:
GROUP BY ...
HAVING SUM(cash) > 500
La clause HAVING
nécessite que vous définissiez une clause GROUP BY.
Pour obtenir la première ligne où la somme 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
Étant donné que la fonction d'agrégation se produit dans une sous-requête, l'alias de colonne correspondant peut être référencé dans la clause WHERE.
Pas 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 uniquement celles où la somme des lignes précédentes est> 500, puis de sauter une et de retourner la suivante.
En général, une condition de 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 soit défini par un ORDER BY
, et il n'y a pas d'ordre implicite dans une table SGBDR.
Vous pouvez utiliser une table dérivée pour joindre chaque ligne au groupe de lignes avec une valeur id
moindre et produire la somme de chaque groupe de somme. Testez ensuite où la somme correspond à 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