2009-02-16 8 views
1

Supposons que j'ai ce codeMySql différences mobiles?

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

donnant cette

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

Comment calculer une colonne de valeurs de b 'où chacun est la différence entre la valeur de « a » dans le courant ligne 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 
+--+--+ 

C'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.

+0

Il est évident dans une feuille de calcul, car faire ces choses est une composante essentielle de son modèle de données. La prémisse du modèle de données relationnelles (google: // algèbre relationnelle) est que chaque table est un ensemble non ordonné de lignes indépendantes - le concept d'une ligne "suivante" ou "précédente" n'existe pas. –

Répondre

2

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

Comme c'est le cas, je pense que la seule façon est avec une sous-requête pour obtenir la plus grande valeur inférieure à la valeur de ligne actuelle, ce qui sera très inefficace. Donc, si vous le pouvez, modifiez 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 ce premier résultat zéro.

Edit: voir cet article pour une visite virtuelle plus complète de cette idée: Calculating differences between successive rows

+0

Super! Merci pour le conseil Paul. Ce lien semble très utile. – kalyanji

+0

Conseil rapide: Si vous ne pouvez pas modifier votre schéma, créez une table temporaire avec un ID dans votre proc, vider votre jeu de résultats là-dedans, puis faites la jointure. – TheSmurf