2017-01-15 9 views
3

Ich habe folgende Datentabelle Bedingung:Wie Summe zwei Spalten in 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 

Grundsätzlich ist diese Tabelle zeigt Informationen über Aufträge und Sendungen pro Markt pro Monat. Das Datum 01-01-2015 in month Spalte stellt tatsächlich Jan 2015 (den ganzen Monat).

Ich möchte SUM die lefttoship_thismonth pro Markt für jeden Monat mit allen vorherigen Monaten. Dies ist erforderlich, da jemand im Januar Bestellungen aufgeben kann, die im Februar geliefert wurden. Ich möchte also wissen, wie viele Artikel ich noch pro Monat versenden muss.

sollte die Ausgabe sein:

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 

Wie kann ich das tun? Ich habe keine Ahnung, wie man auf diese Weise summiert und die month Spalte ist sehr schwer zu arbeiten.

Antwort

3

Sie können es mit einem SubQuery, wenn Ihre Versionen von PostgreSQL nicht (noch) für Fensterfunktionen erlauben):

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 ; 

würden Sie folgendes Ergebnis:

|------------+----------+-----------+--------------+----------------------+------------| 
| 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  | 
|------------+----------+-----------+--------------+----------------------+------------| 

Wenn Sie Fensterfunktionen (die effizienter sind) verwenden können, können Sie Folgendes tun:

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 ; 

Wenn Ihre Spalte month ein Varchar ist (keine gute Idee), können Sie sie auf den neuesten Stand bringen oder die to_date-Funktion verwenden.

3

Sum()Over() Fenster Aggregatfunktion

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

Beat mich ein wenig. :) +1 – GurV

+0

es funktioniert nicht .. es gibt den gleichen Wert für alle Zeilen. – avi

+0

@avi Was ist der Typ Ihrer Spalte 'Monat'? – GurV

2

zu lang für einen Kommentar.

Wenn die Spalte Varchar-Typ ist, müssen Sie sie in ein Datum umwandeln, um es in der Reihenfolge by-Klausel wie folgt zu verwenden.

select t.*, 
    sum(totallefttoship) over 
    (partition by marketid order by to_date(month,'dd-mm-yyyy')) as TOTALLEFT 
From yourtable t 
Verwandte Themen