Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Vergleichen Sie Zeilen in derselben Tabelle in mysql

Sie können einen "Self-Join" (Verbinden der Tabelle mit sich selbst) durchführen, um Abfragen durchzuführen. Der knifflige Teil hier besteht darin, die Reihenfolge zu kennen, in der Zeilen in die Tabelle eingefügt wurden, und nur Zeilen zu vergleichen, die sequentiell (zeitlich) benachbart sind. Ich nehme an, Sie haben eine Art TIMESTAMP-Spalte, die Ihnen sagt, welche Preisänderungen nach den vorherigen erfolgten. Wenn nicht, kann "ID" Sie vielleicht darüber informieren (die größere ID-Zeile wird nach der kleineren ID eingefügt).

Wenn Sie Ihre Tabelle 'TAB' nennen, 'TRADER' verwenden, um den Join bereitzustellen, und 'ID' verwenden, um die Bestellung bereitzustellen, würde die Abfrage einen dreifachen Selbst-Join wie den folgenden erfordern:

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

Die obige Abfrage verknüpft die Tabelle zweimal mit sich selbst, sodass jede Registerkarte Folgendes darstellt:

  • Tab a :Die neuere Zeile zum Vergleich
  • tab b :Die unmittelbar vorherige Zeile, mit der verglichen werden soll
  • Tab c :Eine zeitliche Zeile zwischen a &b (sollte nicht existieren)

Wir führen einen LEFT OUTER JOIN zu 'tab c' durch, weil wir eigentlich nicht wollen, dass diese Zeile existiert. In der where-Klausel filtern wir unsere Ergebnisse nur nach den Ergebnissen, bei denen keine 'tab c'-Zeile vorhanden ist.

Schließlich führt die Abfrage ein 'GROUP BY' für den Händler durch und SUM()s die Inkremente und Dekremente, indem sie den Preis aus den Zeilen 'a' und 'b' vergleicht.

Dies war eine lustige Herausforderung. Hoffe, das hilft!

Johannes...