Somme jusqu'à un certain point - MySql
Question
Comment interroger et afficher les enregistrements jusqu'à atteindre un certain nombre?
Supposons que vous souhaitiez sélectionner un étudiant jusqu'à ce que la somme totale de son argent atteigne 1000?
Ajout
Student ID Student Name Student Money
--------- ----------- --------------
1 John 190
2 Jenny 290
3 Ben 200
4 Andy 120
5 Lynna 300
Si je veux arrêter à 500h, j'aurais les numéros d'enregistrement 1 et 2 (190 + 290). Si je veux m'arrêter à 10 heures, j'aurais le record 1 jusqu'à 4.
La solution
Il n'y a pas "intrinsèque". order à une table SQL, vous devez donc spécifier une clause ORDER BY pour donner cette option "jusqu'à ce que" et phrase n'importe quel sens. Etant donné que, la somme des «premiers» N enregistrements peut être obtenue avec un SELECT SUM (argent) DE l’étudiant ORDER BY xxx LIMIT N. En utilisant une table auxiliaire INTS qui a des entiers dans l’ordre naturel, vous pouvez trouver le maximum approprié. N par quelque chose comme:
SELECT MAX(N) FROM INTS
WHERE (SELECT SUM(money) FROM student ORDER BY xxx LIMIT N) < 1000
et finalement insérez-le comme un autre SELECT imbriqué pour la clause LIMIT dans votre SELECT global. Tout cela sent comme si ce serait plutôt inefficace! Comme souvent lorsque les sélections imbriquées semblent trop nombreuses et trop lentes, une alternative consiste à procéder comme suit: commencez par créer une table temporaire avec les "sommes progressives", puis utilisez-la pour vous aider à trouver la limite dont vous avez besoin.
Autres conseils
Je suis tombé sur cette question en cherchant ma propre réponse. Je pensais laisser ma solution ici car c'est un autre moyen d'accomplir la même tâche et peut être plus efficace. Le truc est la jointure automatique en utilisant > =
SELECT s1.ID, s1.name, s1.money, sum(s2.money)
FROM student s1
INNER JOIN student s2 ON s1.id >= s2.id
GROUP BY s1.id HAVING SUM(s2.money) <= 500;
Oups ... MySQL ... cette solution est destinée à MS SQL ...
Voici une solution utilisant la fonction ROW_NUMBER ().
SELECT Student.*, SUM(StudentBefore.Money) AS AccumulatedMoney
FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber
FROM Students
) AS Student
INNER JOIN
(
SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber
FROM Students
) AS StudentBefore
ON StudentBefore.RowNumber <= Student.RowNumber
GROUP BY Student.RowNumber, Student.Id, Student.Name, Student.Money
HAVING SUM(StudentBefore.Money) < 1000
Le plan d'exécution indique que le tri de la table est l'opération la plus coûteuse. S'il existe un index sur les colonnes à trier - votre exemple indique que vous souhaitez trier selon l'ID de clé primaire - l'analyse de l'index deviendra l'opération la plus coûteuse.