2017-01-30 11 views
0

Ich bin gerade jetzt stecken, jetzt bekommen die Logik, um diese Abfrage zu lösen. Finde die folgenden Tabellen und die Ausgabe. Es gibt Tabelle A und Tabelle B, die zwei Spalten ID und DATE übereinstimmen. Wenn Datum übereinstimmt, dann sollte es die Menge mit Prozent multiplizieren, sonst sollte es vorherige Prozent wählen.Oracle SQL Abfrage vorherige Zeile Ergebnis

Table A     Table B  
ID Date Percent  ID Date Qty 
A 01/01/17 0.5  A 01/01/17 10 
A 04/01/17 1  A 02/01/17 20 
A 06/01/17 2  A 03/01/17 30 
B 02/01/17 5  A 05/01/17 40 
B 05/01/17 10  A 06/01/17 50 
         A 07/01/17 60 
         A 08/01/17 40 
         B 01/01/17 10 
         B 02/01/17 50 

============================================ 

column column column comment comment comment 
    ID Date  Qty   Previous percent if row not matched 
    A 01/01/17 0.5 * 10   0.5 got new percent 
    A 02/01/17 0.5 * 20   0.5 
    A 03/01/17 0.5 * 30   0.5 
    A 04/01/17 1* 0    1 got new percent but no qty found 
    A 05/01/17 1 * 40    1 
    A 06/01/17 2 * 50    2 got new percent 
    B 01/01/17 10 * 0    0 no percent found 
    B 02/02/17 5 * 10    5 got new percent 
    B 5/1/17  10 * 0   10 got new percent 
+0

Die "Ausgang" -Tabelle (??) zeigt eine Zeile für das Datum 04/01/17, das in entweder der Eingangstabellen nicht vorhanden ist. WARUM? Ist das ein Teil der Anforderung? Wenn dies der Fall ist, aktualisieren Sie den Beitrag, um dies explizit zu machen. – mathguy

+0

@mathguy: 04/01/17 ist in der zweiten Zeile der Tabelle A. ??? –

+0

@BobJarvis - Ugh. Ich meinte wirklich in Tabelle B. Allgemeiner - gibt es eine Anforderung, dass alle Monate im Endergebnis vorhanden sind? Aber dann habe ich mir den Rest der Ausgabe angeschaut und es macht keinen Sinn. Was ist zum Beispiel mit 5/5/17? (letzte Reihe in der Ausgabe) Ich entschied, die "Ausgabe" zu ignorieren und das Problem "mein Weg" zu interpretieren. – mathguy

Antwort

0

interpretierte ich das Problem im Sinne von „ein paar mehr Spalten der Tabelle B add“ - den „aktuellen“ Prozentsatz zu zeigen, das Datum aus Tabelle A zeigt, und die „Bruttomenge“ aus der Tabelle B und die "Nettomenge" durch Multiplikation mit dem richtigen Prozentsatz.

Wenn Sie auch für jede Zeile in Tabelle A eine Zeile benötigen, löschen Sie einfach die WHERE-Klausel aus der äußersten Abfrage (am Ende der Abfrage).

with table_a (id, dt, pct) as (
     select 'A', to_date('01/01/17', 'mm/dd/rr'), 0.5 from dual union all 
     select 'A', to_date('04/01/17', 'mm/dd/rr'), 1 from dual union all 
     select 'A', to_date('06/01/17', 'mm/dd/rr'), 2 from dual union all 
     select 'B', to_date('02/01/17', 'mm/dd/rr'), 5 from dual union all 
     select 'B', to_date('05/01/17', 'mm/dd/rr'), 10 from dual 
), table_b (id, dt, qty) as (
     select 'A', to_date('01/01/17', 'mm/dd/rr'), 10 from dual union all 
     select 'A', to_date('02/01/17', 'mm/dd/rr'), 20 from dual union all 
     select 'A', to_date('03/01/17', 'mm/dd/rr'), 30 from dual union all 
     select 'A', to_date('05/01/17', 'mm/dd/rr'), 40 from dual union all 
     select 'A', to_date('06/01/17', 'mm/dd/rr'), 50 from dual union all 
     select 'A', to_date('07/01/17', 'mm/dd/rr'), 60 from dual union all 
     select 'A', to_date('08/01/17', 'mm/dd/rr'), 40 from dual union all 
     select 'B', to_date('01/01/17', 'mm/dd/rr'), 10 from dual union all 
     select 'B', to_date('02/01/17', 'mm/dd/rr'), 50 from dual 
) 
-- end of test data (not part of the SQL query); query begins BELOW THIS LINE 
select id, qty_date, pct_date, qty as gross_qty, pct, qty * pct as net_qty 
from  (select id, dt as qty_date, 
        last_value(case flag when 0 then dt end ignore nulls) 
            over (partition by id order by dt) as pct_date, 
        last_value(pct ignore nulls) 
            over (partition by id order by dt, flag) as pct, 
        qty, flag 
      from (select id, dt, pct, null as qty, 0 as flag 
         from table_a 
        union all 
        select id, dt, null as pct, qty, 1 as flag 
         from table_b 
       ) 
     ) 
where flag = 1  
order by id, qty_date  -- if needed 
; 

Output:

ID QTY_DATE PCT_DATE GROSS_QTY  PCT NET_QTY 
-- ---------- ---------- ---------- ---------- ---------- 
A 2017-01-01 2017-01-01   10   .5   5 
A 2017-02-01 2017-01-01   20   .5   10 
A 2017-03-01 2017-01-01   30   .5   15 
A 2017-05-01 2017-04-01   40   1   40 
A 2017-06-01 2017-06-01   50   2  100 
A 2017-07-01 2017-06-01   60   2  120 
A 2017-08-01 2017-06-01   40   2   80 
B 2017-01-01     10 
B 2017-02-01 2017-02-01   50   5  250 

9 rows selected. 
+0

A 2017-05-01 2017-04-01 40 1 40 << diese Reihe ist falsch sollte es den korrekten Monat anzeigen ... A 2017-04-01 2017-04-01 Null 1 0 fügen Sie eine andere Reihe hinzu A 2017-05-01 2017-05-01 40 1 40 – yAshu

+0

@yAshu - Warum ist 'null' mal (alles) gleich null und nicht auf 'null'? Ansonsten habe ich bereits in meiner Antwort gesagt: "Wenn Sie auch für jede Zeile in Tabelle A eine Zeile benötigen, löschen Sie einfach die WHERE-Klausel von der äußersten Abfrage (am Ende der Abfrage)." Kannst du es finden? Es ist der zweite Absatz in meiner Antwort! Jetzt: Wenn Sie für 'net_qty' null anstelle von' NULL' anzeigen müssen, wählen Sie '' coalesce (qty, 0) * pct als net_qty' anstatt einfach 'qty * pct' im' SELECT' der äußeren Abfrage. Ich nehme an, wenn du 'pct' nicht hast (erste Reihe für B), dann sollte' net_qty' immer noch 'null' sein, oder? – mathguy

+0

Ich verwendete die gleiche Logik in meiner Abfrage mit analytischen Funktion LAST VALUE .... Ich kam hierher, um zu wissen, ob es eine andere alternative Lösung dieser Abfrage geben könnte ... aber Sie schrieben die ungefähr gleiche Lösung ... Nun, danke @mathguy. Kudos !! – yAshu