9

我想在 SQLite 中创建一个视图,其中一行中的字段取决于前一行中字段的值。我可以使用LAG分析函数在 Oracle 中执行此操作,但不确定如何在 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'
4

4 回答 4

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子句中。

于 2012-04-05T07:33:07.720 回答
2

Oracle 等效项是正确的。从SQLite 3.25.0开始,您可以LAG本机使用:

WITH mytable(ITEM,DAY,PRICE) AS (
    VALUES
    ('apple',  CAST('20110107' AS DATE),    1.25),
    ('orange', CAST('20110102' AS DATE),    1.00),
    ('apple',  CAST('20110101' AS DATE),    1.00),
    ('orange', CAST('20110103' AS DATE),    2.00),
    ('apple',  CAST('20110108' AS DATE),    2.00),
    ('apple',  CAST('20110110' AS DATE),    1.50)
)
SELECT day, price, price-LAG(price) OVER (ORDER BY day) AS change
FROM mytable
WHERE item = 'apple'
ORDER BY DAY;

db<>小提琴演示

于 2018-08-17T19:31:22.977 回答
2

这应该对每个人都有效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排序,然后只对第一个值进行排序,模拟一个函数。LIMITLAG

对于一个LEAD行为,只需翻转<>DESCto ASC

于 2017-12-04T10:07:50.670 回答
0

假设您不删除这将起作用:


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

这是有效的,因为即使您没有在CREATE语句中指定它,每一行都有自己的 rowid。

如果你删除,它变成:


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

这是在 rowids 总是增加的假设下工作的。

于 2012-04-04T00:37:40.853 回答