2016-06-14 2 views
0

Ich versuche kumulativ Umsatz aus den letzten Jahren zu addieren, um das Guthaben auf den ersten Monat zu bringen und dieses von Monat zu Monat fortzusetzen. Zum Beispiel, wenn wir die folgenden Daten:Kumulative Aufsummierung von Verkäufen aus den letzten Jahren Abschlusssaldo zu aktuellen Jahren Eröffnungsbilanzen

select 4 id, 'A' name, 'group1' group, '2015' year, '10' month, 20 sales from dual union all 
select 5 id, 'C' name,'group2' group, '2015' year, '12' month, 89 sales from dual union all 
select 13 id,'B' name, 'group2' group, '2016' year, '01' month, 10 sales from dual union all 
select 14 id,'A' name, 'group3' group, '2016' year, '02' month, 8 sales from dual union all 
select 15 id,'B' name, 'group1' group, '2016' year, '02' month, 16 sales from dual union all 
select 16 id,'D' name,'group2' group, '2016' year, '04' month, 15 sales from dual union all 
select 17 id,'D' name,'group4' group, '2016' year, '05' month, 23 sales from dual union all 
select 18 id,'D' name,'group3' group, '2016' year, '06' month, 39 sales from dual union all 
select 19 id,'D' name,'group3' group, '2016' year, '07' month, 45 sales from dual union all 
select 20 id,'D' name,'group3' group, '2016' year, '08' month, 12 sales from dual union all 
select 21 id,'D' name,'group4' group, '2016' year, '09' month, 20 sales from dual union all 
select 22 id,'D' name,'group3' group, '2016' year, '10' month, 4 sales from dual union all 
select 23 id,'D' name,'group3' group, '2016' year, '11' month, 98 sales from dual union all 
select 24 id,'D' name,'group4' group, '2016' year, '12' month, 70 sales from dual 

Hinweis für Jahr = 2015 die Schlussbilanz für dieses Jahr Monat = 12 Balance ist in diesem Fall die 89 für group2 und 20 für Gruppe 1 ist. Wenn wir im Jahr 2016 sind, mag ich die kumulative Abfrage so etwas wie dies zurück:

year, month, group, opening_balance, closing_balance 
2016 01 group2  89    99    (89+10) 
2016 02 group3  0    8     (0+8) 
2016 02 group1  20    36    (20 + 16) 
2016 04 group2  99    114    (99 + 15) 
2016 05 group4  0    23    (0 + 23 - note group4 has no prior balances) 
2016 06 group3  8    47    (8 + 39) 
2016 07 group3  47    92    (47 + 45) 
and so on 

Das sieht aus wie benötigt er die analytische Funktion sum() über die (Partition .... order by ...)

Aber ich habe nicht den richtigen Weg gefunden, dies zu tun.

Vielen Dank im Voraus.

+0

Warum Sie Jahr und Monat als Text in zwei Spalten zu speichern? Es wäre besser als einzelne "DATE" -Spalte gespeichert und wenn Sie die separaten Komponenten möchten, können Sie 'EXTRACT (YEAR FROM Verkaufsdatum) 'oder' TO_CHAR (Verkaufsdatum,' MM ') 'verwenden. – MT0

+0

Sie haben 'group3' mit einer Anfangsbalance von 99 - dies spiegelt sich jedoch nicht in den Beispieldaten wider. Woher kam die 99? – MT0

+0

MT0 Sie haben Recht. Behoben. Danke, dass Sie das notieren – bytebiscuit

Antwort

1

Oracle-Setup:

CREATE TABLE sales (id, name, grp, year, month, sales) AS 
    SELECT 4, 'A', 'group1', '2015', '10', 20 FROM DUAL UNION ALL 
    SELECT 5, 'C', 'group2', '2015', '12', 89 FROM DUAL UNION ALL 
    SELECT 13, 'B', 'group2', '2016', '01', 10 FROM DUAL UNION ALL 
    SELECT 14, 'A', 'group3', '2016', '02', 8 FROM DUAL UNION ALL 
    SELECT 15, 'B', 'group1', '2016', '02', 16 FROM DUAL UNION ALL 
    SELECT 16, 'D', 'group2', '2016', '04', 15 FROM DUAL UNION ALL 
    SELECT 17, 'D', 'group4', '2016', '05', 23 FROM DUAL UNION ALL 
    SELECT 18, 'D', 'group3', '2016', '06', 39 FROM DUAL UNION ALL 
    SELECT 19, 'D', 'group3', '2016', '07', 45 FROM DUAL UNION ALL 
    SELECT 20, 'D', 'group3', '2016', '08', 12 FROM DUAL UNION ALL 
    SELECT 21, 'D', 'group4', '2016', '09', 20 FROM DUAL UNION ALL 
    SELECT 22, 'D', 'group3', '2016', '10', 4 FROM DUAL UNION ALL 
    SELECT 23, 'D', 'group3', '2016', '11', 98 FROM DUAL UNION ALL 
    SELECT 24, 'D', 'group4', '2016', '12', 70 FROM DUAL; 

Abfrage:

SELECT * 
FROM (
    SELECT year, 
     month, 
     grp, 
     COALESCE(
      SUM(sales) OVER (PARTITION BY grp 
           ORDER BY dt 
           RANGE BETWEEN UNBOUNDED PRECEDING 
             AND INTERVAL '1' MONTH PRECEDING 
          ), 
      0 
     ) AS opening_balance, 
     SUM(sales) OVER (PARTITION BY grp 
          ORDER BY dt 
          RANGE BETWEEN UNBOUNDED PRECEDING 
             AND CURRENT ROW 
          ) AS closing_balance 
    FROM (
    SELECT s.*, 
      TO_DATE(year || month, 'YYYYMM') AS dt 
    FROM sales s 
) 
) 
WHERE year = 2016 
ORDER BY year, month, grp; 

Abfrage - Alternative ohne RANGE BETWEEN:

SELECT * 
FROM (
    SELECT year, 
     month, 
     grp, 
     SUM(sales) OVER (PARTITION BY grp 
          ORDER BY year, month) 
      - sales AS opening_balance, 
     SUM(sales) OVER (PARTITION BY grp 
          ORDER BY year, month 
          ) AS closing_balance 
    FROM sales 
) 
WHERE year = 2016 
ORDER BY year, month, grp; 

Ausgang:

YEAR MO GRP OPENING_BALANCE CLOSING_BALANCE 
---- -- ------ --------------- --------------- 
2016 01 group2    89    99 
2016 02 group1    20    36 
2016 02 group3    0    8 
2016 04 group2    99    114 
2016 05 group4    0    23 
2016 06 group3    8    47 
2016 07 group3    47    92 
2016 08 group3    92    104 
2016 09 group4    23    43 
2016 10 group3    104    108 
2016 11 group3    108    206 
2016 12 group4    43    113 
+0

Fehler auf dem BEREICH ZWISCHEN UNBOUNDED PRECEDING UND INTERVALL '1' MONAT PRECEDING – bytebiscuit

+0

Zu sagen, Sie haben einen "Fehler" ist nicht hilfreich zu erarbeiten, was schief gelaufen ist - was ist der Fehler? – MT0

+0

@bytebiscuit Aktualisiert mit Beispieleingabe und -ausgabe. Der Code, den Sie sagen, hat einen Fehler ist jedoch unverändert und es funktioniert auf meinem System (Oracle 11.2.0.1). – MT0

Verwandte Themen