2017-01-15 64 views
3

兩列,我有以下數據表:如何有條件總和的PostgreSQL 9.3

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 

基本上這個表顯示有關每月訂單和每個市場出貨信息。 month列中的日期01-01-2015列實際上代表Jan 2015(整個月)。

我想SUMlefttoship_thismonth每個月與前幾個月的月份。這是需要的,因爲有人可以在一月份下訂單,這是在二月份提供的。所以我想知道每月還需要運送多少物品。

輸出應該是:

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列是非常難以處理。

回答

3

你可以用一個子查詢做到這一點,如果你的PostgreSQL的版本並沒有(還)允許窗口功能):

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函數。

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

擊敗我一點點。 :) +1 – GurV

+0

它不起作用..它給所有行相同的值。 – avi

+0

@avi'month'列的類型是什麼? – GurV

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