我有以下数据表:
month marketid totalsold totalshipped lefttoship_thismonth
....
01-01-2015 1 100 50 50
01-01-2015 2 10 3 7
01-01-2015 3 0 0 0
01-02-2015 1 0 50 -50
01-02-2015 2 20 0 20
01-02-2015 3 0 0 0
此表基本上显示了每月每个市场的订单和发货量信息。
01-01-2015
列中的month
日期实际上代表Jan 2015
(整个月)。
我希望每月每个市场SUM
lefttoship_thismonth
与前几个月相比。这是必要的,因为有人可以在2月份提供1月订单。所以我想知道每个月还需要运送多少物品。
输出应为:
month marketid totalsold totalshipped totallefttoship TOTALLEFT
01-01-2015 1 100 50 50 50
01-01-2015 2 10 3 7 7
01-01-2015 3 0 0 0 0
01-02-2015 1 0 50 -50 0 /50-50
01-02-2015 2 20 0 20 27 /7+20
01-02-2015 3 0 0 0 0 / 0+0
我该怎么做?
我不知道如何以这种方式加总,month
列非常难以使用。
答案 0 :(得分:3)
Sum()Over()
窗口聚合函数
SELECT "month",
marketid,
totalsold,
totalshipped,
lefttoship_thismonth,
Sum(lefttoship_thismonth)OVER(partition BY marketid ORDER BY month ) AS TOTALLEFT
FROM yourtable
ORDER BY "month",
marketid
答案 1 :(得分:3)
如果您的PostgreSQL版本(还)不允许窗口函数,您可以使用SubQuery执行此操作:
WITH t (month, marketid, totalsold, totalshipped, lefttoship_thismonth) AS
(VALUES
('01-01-2015'::date, 1, 100, 50, 50),
('01-01-2015'::date, 2, 10, 3, 7),
('01-01-2015'::date, 3, 0, 0, 0),
('01-02-2015'::date, 1, 0, 50, -50),
('01-02-2015'::date, 2, 20, 0, 20),
('01-02-2015'::date, 3, 0, 0, 0)
)
SELECT
month,
marketid,
totalsold,
totalshipped,
lefttoship_thismonth,
(SELECT sum(lefttoship_thismonth)
FROM t t2
WHERE t2.marketid = t1.marketid AND
t2.month <= t1.month
) AS total_left
FROM
t t1
ORDER BY
month, marketid ;
会得到以下结果:
|------------+----------+-----------+--------------+----------------------+------------|
| month | marketid | totalsold | totalshipped | lefttoship_thismonth | total_left |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-01 | 1 | 100 | 50 | 50 | 50 |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-01 | 2 | 10 | 3 | 7 | 7 |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-01 | 3 | 0 | 0 | 0 | 0 |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-02 | 1 | 0 | 50 | -50 | 0 |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-02 | 2 | 20 | 0 | 20 | 27 |
|------------+----------+-----------+--------------+----------------------+------------|
| 2015-01-02 | 3 | 0 | 0 | 0 | 0 |
|------------+----------+-----------+--------------+----------------------+------------|
如果您可以使用Window功能(效率更高),您可以执行以下操作:
SELECT
month,
marketid,
totalsold,
totalshipped,
lefttoship_thismonth,
( sum(lefttoship_thismonth)
OVER (PARTITION BY marketid ORDER BY month ROWS UNBOUNDED PRECEDING)
) AS total_left
FROM
t t1
ORDER BY
month, marketid ;
如果您的month
列是varchar(不是一个好主意),您可以将其转换为日期,或使用to_date
函数。
答案 2 :(得分:2)
评论太长了。
如果列是varchar类型,那么你必须将它转换为日期才能在order by子句中使用它。就像这样。
select t.*,
sum(totallefttoship) over
(partition by marketid order by to_date(month,'dd-mm-yyyy')) as TOTALLEFT
From yourtable t