Question

Supposons que j'ai ce code

create temporary table somedata (a integer);
insert into somedata (a) values (11), (25), (62); --#these values are always increasing
select * from somedata;

donner cette

+--+
|a |
+--+
|11|
|25|
|62|
+--+

Comment calculer une colonne de 'b' valeurs où chacun est la différence entre la valeur de « a » dans la rangée courante et la valeur de « a » dans la rangée précédente?

+--+--+
|a |b |
+--+--+
|11| 0| # ie 11-11 since theres no preceding row
|25|14| # ie 25-11
|62|37| # ie 62-25 etc
+--+--+

Ceci est tellement évident dans openoffice ou Excel que je me sens un peu stupide de ne pas avoir encore trouvé comment faire sur le site de MySql, ni nulle part ailleurs.

Était-ce utile?

La solution

Il serait plus facile si vous aviez une colonne AUTO_INCREMENT pour donner à chaque ligne son propre id - vous pouvez alors rejoindre la table contre elle-même sur (alias2.id = alias1.id + 1) et calculer la diff de alias2.a-alias1 .a

Comme il est, je pense que la seule façon est une sous-requête pour obtenir la plus grande valeur une inférieure à la valeur actuelle de la ligne, qui sera très inefficace.

Donc, si vous pouvez, modifier votre schéma!

create table somedata (
    id int auto_increment not null, 
    a integer, 
    primary key(id)
);
insert into somedata (a) values (11), (25), (62); 

select a2.a,ifnull(a2.a-a1.a, 0) as diff  
from somedata  as a1 
right join somedata  as a2 on (a2.id=a1.id+1);

+------+------+
| a    | diff |
+------+------+
|   11 |    0 |
|   25 |   14 |
|   62 |   37 |
+------+------+

Utilisez jointure interne plutôt une jointure droite si vous ne voulez pas que le premier résultat nul.

Edit: voir cet article pour une visite virtuelle plus complète de cette idée: calculer des différences entre des rangées successives

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top