2012-04-04 67 views
7

我想在SQLite中創建一個視圖,其中一行中的字段取決於前一行中的一個字段的值。我可以在Oracle中使用LAG分析函數完成此操作,但不確定如何在SQLite中進行操作。創建一個SQLite視圖,其中一行取決於前一行

例如,如果我的表看起來像:

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 

我想我的觀點的樣子,與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 

編輯:

的等效我正在尋找的查詢會在Oracle看起來像(沒有嘗試過,但我認爲這是正確的):

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

定義「上一個」。看起來像是當前記錄前一天的單個允許記錄。這總是如此嗎? – 2012-04-04 01:15:42

+0

不,我已經擴展了這個例子。通過「之前」,我基本上是指在所討論的行之前的行列,一旦它們被訂購。 – eaolson 2012-04-04 01:41:55

+0

定義「有序」。基本上,問題在於SQL數據庫(根據定義)沒有行定序的概念,除了專門指定的內容(按列名稱)檢索時。通常你可以得到你想要的結果,但是你必須通過你的視圖定義中的關係代數來導出「前一行」,爲此,你需要非常清楚你如何在plain中定義「previous」語言。 – 2012-04-04 10:51:03

回答

0

假設你不刪除這將工作:


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

這工作,因爲每一行都有自己的rowid,即使你不中CREATE語句中指定它。

如果確實刪除了,就變成:


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 

這工作假設的rowid總是在不斷增加。

+0

這使得我們不願意做出關於表歷史的假設(爲了插入行,從未更新等)。 – eaolson 2012-04-04 01:44:43

2

它與其他的想法相同,只是使用字段而不是rowid。這不正是你想要什麼:


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 

如果你想添加的WHERE item='apple'位你是添加到這兩個WHERE條款。

1

這應該做的每item招(上SQLite的測試):

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 

這是假設之間dayitem是獨特的組合。它的工作方式是通過取所有值小於給定day,排序然後LIMIT只是第一個值,模擬LAG功能。

對於LEAD行爲,只需將<改爲>DESC改爲ASC即可。

相關問題