2012-04-04 30 views
7

Tôi muốn tạo chế độ xem trong SQLite trong đó một trường trong một hàng phụ thuộc vào giá trị của trường trong hàng trước đó. Tôi có thể làm điều này trong Oracle bằng cách sử dụng chức năng phân tích LAG, nhưng không chắc chắn làm thế nào để đi về nó trong SQLite.Tạo chế độ xem SQLite trong đó hàng phụ thuộc vào hàng trước

Ví dụ, nếu bàn của tôi trông giống như:

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 

Tôi muốn quan điểm của tôi trông giống như, với 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:

Tương đương của truy vấn Tôi đang tìm kiếm sẽ tìm trong Oracle một cái gì đó như (chưa thử này, nhưng tôi nghĩ rằng điều này là chính xác):

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

Xác định "trước". Có vẻ như bản ghi được phép duy nhất cho ngày một ngày trước bản ghi hiện tại. Điều đó luôn đúng không? –

+0

No. Tôi đã mở rộng ví dụ. Bởi "trước" tôi về cơ bản có nghĩa là hàng hàng trước khi một trong những câu hỏi, một khi họ đang đặt hàng. – eaolson

+0

Xác định "đã đặt hàng". Về cơ bản, vấn đề là cơ sở dữ liệu SQL (theo định nghĩa) không có khái niệm về thứ tự hàng ngoài những gì bạn chỉ định cụ thể, theo tên cột, khi truy xuất. Bạn có thể nhận được kết quả mong muốn, nhưng bạn sẽ phải lấy "hàng trước" thông qua đại số quan hệ trong định nghĩa khung nhìn của bạn và, để làm điều đó, bạn cần phải rõ ràng về cách bạn định nghĩa "trước" ở đồng bằng ngôn ngữ. –

Trả lời

0

Giả sử rằng bạn không xóa này sẽ làm việc:


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

này hoạt động vì mỗi hàng có rowid riêng của mình ngay cả khi bạn không xác định nó trong báo cáo CREATE.

Nếu bạn xóa, nó trở thành:


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 

này hoạt động theo giả định rằng rowids luôn tăng.

+0

Điều đó làm cho các giả định về lịch sử của bảng (thứ tự các hàng được chèn vào, chúng không bao giờ được cập nhật, vv) mà tôi không muốn thực hiện. – eaolson

2

Ý tưởng giống như ý tưởng khác, nhưng chỉ sử dụng các trường thay vì hàng. Đây thực hiện chính xác những gì bạn muốn:


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 

Nếu bạn muốn thêm chút WHERE item='apple' bạn muốn thêm rằng cả WHERE khoản.

1

này nên làm các trick cho mỗi item (thử nghiệm trên 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 

này giả định sự kết hợp giữa dayitem là duy nhất. Và cách hoạt động của nó là lấy tất cả các giá trị nhỏ hơn cho trước day, phân loại giảm dần và sau đó chỉgiá trị đầu tiên, mô phỏng hàm LAG.

Đối với hành vi LEAD, chỉ cần lật < tới >DESC đến ASC.

Các vấn đề liên quan