2012-04-04 29 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即可。

相关问题