我想将前一个值与该行中的现有值相加。
这是我的代码:
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')
表格应该是这样的:
谢谢。
答案 0 :(得分: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
答案 1 :(得分:0)
您可以使用Window Functions with Frame子句。
如果你想与前一行进行SUM,那么你将会这样做:
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
。
如果您希望与之前的所有行(运行总计)进行SUM,那么您将执行以下操作:
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
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;