2012-04-04 19 views
7

Ich möchte eine Ansicht in SQLite erstellen, in der ein Feld in einer Zeile vom Wert eines Felds in der vorherigen Zeile abhängt. Ich könnte dies in Oracle mit der analytischen Funktion LAG tun, aber nicht sicher, wie es in SQLite zu gehen.Erstellen einer SQLite-Ansicht, in der eine Zeile von der vorherigen Zeile abhängt

Zum Beispiel, wenn mein Tisch aussieht:

ITEM  DAY   PRICE 
apple  2011-01-07 1.25 
orange  2011-01-02 1.00 
apple  2011-01-01 1.00 
orange  2011-01-03 2.00 
apple  2011-01-08 1.00 
apple  2011-01-10 1.50 

ich meine Ansicht nach aussehen möchte, mit WHERE item = 'apple':

DAY   PRICE CHANGE 
2011-01-01 1.00  (null) 
2011-01-07 1.25  0.25 
2011-01-08 2.00  0.75 
2011-01-10 1.50  -0.50 

Edit:

Das Äquivalent der Abfrage, die ich suchen würde in Oracle etwas aussehen (habe nicht versucht, aber ich denke, das ist richtig):

SELECT day, price, 
     price - LAG(price, 1) OVER (ORDER BY day) AS change 
    FROM mytable 
WHERE item = 'apple' 
+0

Definieren Sie "vorherige". Sieht aus wie der einzige erlaubte Datensatz für das Datum einen Tag vor dem aktuellen Datensatz. Ist das immer wahr? –

+0

Nein. Ich habe das Beispiel erweitert. Mit "vorhergehend" meine ich im Grunde die Zeile Zeile vor der fraglichen, sobald sie bestellt sind. – eaolson

+0

Definieren Sie "geordnet". Grundsätzlich besteht das Problem darin, dass SQL-Datenbanken (per definitionem) kein Konzept der Zeilenreihenfolge haben, abgesehen von dem, was Sie beim Abrufen speziell nach dem Spaltennamen angeben. Sie können im Allgemeinen das gewünschte Ergebnis erhalten, aber Sie müssen die "vorherige Zeile" über die relationale Algebra in Ihrer Ansichtsdefinition ableiten, und um dies zu tun, müssen Sie sich sehr klar darüber sein, wie Sie "vorheriges" im Allgemeinen definieren Sprache. –

Antwort

0

Unter der Annahme, dass Sie dies nicht funktionieren, löschen:


SELECT t2.DAY, t2.price, t2.price-t1.price 
FROM TABLENAME t1, TABLENAME t2 
WHERE t1.rowid=t2.rowid-1 

Das funktioniert, weil jede Zeile eine eigene Rowid hat, auch wenn Sie spezifizieren nicht, dass es in der CREATE Aussage.

Wenn Sie löschen Sie, es wird:


SELECT t2.day, t2.price, t2.price-t1.price 
FROM 
    (SELECT l1.day, l1.price, 
      (SELECT COUNT(*) 
      FROM TABLENAME l2 
      WHERE l2.rowid < l1.rowid) AS count 
     FROM TABLENAME l1) AS t1, 
    (SELECT l1.day, l1.price, 
      (SELECT COUNT(*) 
      FROM TABLENAME l2 
      WHERE l2.rowid < l1.rowid) AS count 
     FROM TABLENAME l1) AS t2 
WHERE t1.count=t2.count-1 

Dies unter der Annahme arbeitet, dass ROWIDs immer steigen.

+0

Das macht Annahmen über die Geschichte der Tabelle (Reihenfolge der Zeilen eingefügt wurden, dass sie nie aktualisiert werden, etc.), die ich lieber nicht machen würde. – eaolson

2

Es ist die gleiche Idee wie die andere, aber verwendet nur die Felder anstelle der Rowid. Dies ist genau das, was Sie wollen:


CREATE TABLE Prices (
    day DATE, 
    price FLOAT 
); 

INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '+1 day'), 0.5); 
INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '+0 day'), 1); 
INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '-1 day'), 2); 
INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '-2 day'), 7); 
INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '-3 day'), 8); 
INSERT INTO Prices(day, price) VALUES(date('now', 'localtime', '-4 day'), 10); 

SELECT p1.day, p1.price, p1.price-p2.price 
FROM 
    Prices p1, Prices p2, 
    (SELECT t2.day AS day1, MAX(t1.day) AS day2 
    FROM Prices t1, Prices t2 
    WHERE t1.day < t2.day 
    GROUP BY t2.day) AS prev 
WHERE p1.day=prev.day1 
    AND p2.day=prev.day2 

Wenn Sie das WHERE item='apple' Bit hinzufügen möchten Sie, dass zu beiden WHERE Klauseln hinzufügen würde.

1

Dies sollte den Trick für jeden item (auf SQLite getestet):

SELECT 
    day 
    ,price 
    ,price - (SELECT t2.price 
       FROM mytable t2 
       WHERE 
        t2.item = t1.item AND 
        t2.day < t1.day  
       ORDER BY t2.day DESC 
       LIMIT 1 
      ) AS change 
FROM mytable t1 

Dies setzt voraus, die Kombination zwischen day und item einzigartig ist. Und so, wie es funktioniert, ist durch alle Werte unter weniger als die gegebenen day, Sortierung absteigend und dann LIMIT nur der erste Wert, die Simulation eine LAG Funktion.

Für ein LEAD Verhalten, Flip nur <-> und DESC-ASC.

Verwandte Themen