2017-06-21 25 views
3

我想將前一個值與該行中的現有值相加。在SELECT語句中將「前一行」值與現有行值相加

這裏是我的代碼:

select co.partner_id, to_char(co.date, 'DD') as day, to_char(co.date, 'MM') as month, to_char(co.date, 'YYYY') as year, 
     sum(col.qty * p.price) as priceday 


from order_detail col 
join order co on co.id=col.order_id 
join product p on p.id = col.product_id 

group by co.partner_id, to_char(co.date, 'MM'), to_char(co.date, 'YYYY'), to_char(co.date, 'DD') 

的代碼變成了這個樣子:IMAGE TABLE

表前人的精力是這樣的: IMAGES

謝謝。

回答

1

下面是你需要什麼(我希望)一個例子:

test=# with nums(n) as (
    select z from generate_series(1, 10) as _(z) 
) 
select 
    n, 
    sum(n) over (order by n) 
from nums; 
n | sum 
----+----- 
    1 | 1 
    2 | 3 
    3 | 6 
    4 | 10 
    5 | 15 
    6 | 21 
    7 | 28 
    8 | 36 
    9 | 45 
10 | 55 
(10 rows) 

這就是所謂的「窗口功能」,看文檔在這裏:https://www.postgresql.org/docs/current/static/tutorial-window.html

0

您可以使用窗口函數與框架條款。

如果你想與前一行來概括,那麼你會做什麼:

SELECT o.partner_id, o.date, SUM(SUM(p.price * od.qty)) OVER (PARTITION BY o.partner_id ORDER BY o.partner_id, o.date ROWS 1 PRECEDING) AS priceday 
    FROM test.order AS o 
    INNER JOIN test.order_detail AS od 
     ON o.id = od.order_id 
    INNER JOIN test.product AS p 
     ON od.product_id = p.id 
    GROUP BY o.partner_id, o.date; 

通知的ROWS 1 PRECEDING

如果你想與所有以前行(運行總量)來總結,你會做什麼:

SELECT o.partner_id, o.date, SUM(SUM(p.price * od.qty)) OVER (PARTITION BY o.partner_id ORDER BY o.partner_id, o.date ROWS UNBOUNDED PRECEDING) AS priceday 
    FROM test.order AS o 
    INNER JOIN test.order_detail AS od 
     ON o.id = od.order_id 
    INNER JOIN test.product AS p 
     ON od.product_id = p.id 
    GROUP BY o.partner_id, o.date; 

通知的ROWS UNBOUNDED PRECEDING

說明

SUM(SUM(p.price * od.qty)) OVER (PARTITION BY o.partner_id ORDER BY o.partner_id, o.date ROWS 1 PRECEDING) AS priceday是主要演員:

  • SUM(p.price * od.qty) - 計算每天的價格
  • SUM(SUM(...)) OVER (...) - 爲了要求 - 多天
  • PARTITION BY o.partner_id款項多種價格將SUM保持在partner_id
  • 01的邊界內
  • ORDER BY o.partner_id, o.date - 根據日期
  • ROWS 1 PRECEDING訂購分區內的行所需 - 爲了包括在SUM上一行與當前行

完整示例(更容易測試)

沿
CREATE SCHEMA test; 

CREATE TABLE test.order (
    id SERIAL PRIMARY KEY, 
    partner_id int, 
    date date 
); 

CREATE TABLE test.product (
    id SERIAL PRIMARY KEY, 
    price DECIMAL 
); 

CREATE TABLE test.order_detail (
    id SERIAL PRIMARY KEY, 
    order_id int REFERENCES test.order (id), 
    product_id int REFERENCES test.product (id), 
    qty int 
); 

INSERT INTO test.order 
    (partner_id, date) 
    VALUES 
    (531, '2017-06-20'), 
    (531, '2017-06-21'), 
    (531, '2017-06-22'), 
    (532, '2017-06-20'), 
    (532, '2017-06-20'), 
    (532, '2017-06-22'), 
    (532, '2017-06-23'); 

INSERT INTO test.product 
    (price) 
    VALUES 
    (1000.0); 

INSERT INTO test.order_detail 
    (order_id, product_id, qty) 
    VALUES 
    (1, 1, 300), 
    (2, 1, 230), 
    (3, 1, 130), 
    (4, 1, 300), 
    (5, 1, 230), 
    (6, 1, 130), 
    (7, 1, 100); 

-- sum with the previous row 
SELECT o.partner_id, o.date, SUM(SUM(p.price * od.qty)) OVER (PARTITION BY o.partner_id ORDER BY o.partner_id, o.date ROWS 1 PRECEDING) AS priceday 
    FROM test.order AS o 
    INNER JOIN test.order_detail AS od 
     ON o.id = od.order_id 
    INNER JOIN test.product AS p 
     ON od.product_id = p.id 
    GROUP BY o.partner_id, o.date; 

-- sum with all the previous rows 
SELECT o.partner_id, o.date, SUM(SUM(p.price * od.qty)) OVER (PARTITION BY o.partner_id ORDER BY o.partner_id, o.date ROWS UNBOUNDED PRECEDING) AS priceday 
    FROM test.order AS o 
    INNER JOIN test.order_detail AS od 
     ON o.id = od.order_id 
    INNER JOIN test.product AS p 
     ON od.product_id = p.id 
    GROUP BY o.partner_id, o.date; 

DROP SCHEMA test CASCADE;