Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comparer les lignes dans la même table dans mysql

Vous pouvez effectuer une « auto-jointure » (joindre la table à elle-même) pour effectuer des requêtes. La partie délicate ici est de connaître l'ordre dans lequel les lignes ont été insérées dans le tableau et de ne comparer que les lignes séquentiellement (temporellement) adjacentes. Je suppose que vous avez une sorte de colonne TIMESTAMP qui vous indiquera quels changements de prix sont intervenus après les précédents. Si ce n'est pas le cas, "ID" peut peut-être vous en informer (la ligne d'ID supérieure étant insérée après l'ID inférieur).

En appelant votre table 'TAB', en utilisant 'TRADER' pour fournir la jointure et en utilisant 'ID' pour fournir l'ordre, la requête nécessiterait une auto-jointure à trois voies comme suit :

SELECT a.trader
     , SUM(IF(a.price > b.price, 1, 0)) nbr_incr
     , SUM(IF(a.price < b.price, 1, 0)) nbr_decr
     , SUM(IF(a.price = b.price, 1, 0)) nbr_same
  FROM tab a
  JOIN tab b 
    ON a.trader = b.trader AND a.id > b.id
  LEFT OUTER JOIN tab c 
    ON a.trader = c.trader AND a.id > c.id AND b.id < c.id
 WHERE c.id IS NULL
 GROUP BY a.trader

La requête ci-dessus joint la table à elle-même deux fois afin que chaque onglet représente ce qui suit :

  • tab a :la ligne la plus récente pour la comparaison
  • tab b :la ligne immédiatement précédente à comparer
  • tab c :une ligne entre a et b dans le temps (ne devrait pas exister)

Nous effectuons un LEFT OUTER JOIN à 'tab c' parce que nous ne voulons pas que cette ligne existe. Dans la clause where, nous filtrons nos résultats uniquement sur les résultats où une ligne 'tab c' n'existe pas.

Enfin, la requête effectue un 'GROUP BY' sur le trader, et SOMME()s les incréments et les décréments en comparant le prix des lignes 'a' et 'b'.

C'était un défi amusant. J'espère que cela vous aidera !

Jean...