In Orakel, die LISTAGG
Funktion ermöglicht es mir, es analytisch mit einer OVER (PARTITION BY column..)
Klausel zu verwenden. Die Verwendung von Fenstern mit den Schlüsselwörtern ROWS
oder RANGE
wird jedoch nicht unterstützt.LISTAGG äquivalent mit Windowing-Klausel
Ich habe einen Datensatz aus einem Geschäft registrieren (vereinfacht für die Frage). Beachten Sie, dass die Menge der Registertabelle immer 1 - ein Element, eine Transaktionszeile ist.
TranID TranLine ItemId OrderID Dollars Quantity
------ -------- ------ ------- ------- --------
1 101 23845 23 2.99 1
1 102 23845 23 2.99 1
1 103 23845 23 2.99 1
1 104 23845 23 2.99 1
1 105 23845 23 2.99 1
Ich muss diese Daten mit einer Tabelle in einem speziellen Bestellsystem "zusammenpassen", in dem Artikel nach Menge gruppiert sind. Beachten Sie, dass das System dieselbe Artikel-ID für mehrere Zeilen haben kann (die bestellten Komponenten können sich unterscheiden, auch wenn der Artikel identisch ist).
ItemId OrderID Order Line Dollars Quantity
------ ------- ---------- ------- --------
23845 23 1 8.97 3
23845 23 2 5.98 2
Die nur Art, wie ich diese Daten übereinstimmen kann, ist durch Auftrags-ID, Artikel-ID und Dollar-Betrag.
Im Wesentlichen muss ich zu dem folgenden Ergebnis gelangen.
ItemId OrderID Order Line Dollars Quantity Tran ID Tran Lines
------ ------- ---------- ------- -------- ------- ----------
23845 23 1 8.97 3 1 101;102;103
23845 23 2 5.98 2 1 104;105
ich nicht speziell egal, ob die tran Linien in irgendeiner Weise geordnet sind, meinetwegen ist, dass die Dollar-Beträge übereinstimmen und dass ich nicht „Wiederverwendung“ eine Zeile aus dem Register in Computing die Summe auf der Sonderbestellung. Ich brauche die tran-Zeilen nicht in eine Tabelle aufgeteilt - das ist für Reporting-Zwecke und die Granularität geht nie zurück auf die Ebene der Registertransaktionszeile.
Meine anfängliche Meinung war, dass ich dies mit analytischen Funktionen tun kann, um eine "beste Übereinstimmung" zu finden, um die erste Menge von Zeilen zu identifizieren, die dem Dollarbetrag und -menge im Bestellsystem entsprechen :
TranID TranLine ItemId OrderID Dollars Quantity CumDollar CumQty
------ -------- ------ ------- ------- -------- -------- ------
1 101 23845 23 2.99 1 2.99 1
1 102 23845 23 2.99 1 5.98 2
1 103 23845 23 2.99 1 8.97 3
1 104 23845 23 2.99 1 11.96 4
1 105 23845 23 2.99 1 14.95 5
So weit so gut. Aber ich versuche dann LISTAGG meiner Abfrage hinzuzufügen:
SELECT tranid, tranline, itemid, orderid, dollars, quantity,
SUM(dollars) OVER (partition by tranid, itemid, orderid order by tranline) cumdollar,
SUM(quantity) OVER (partition by tranid, itemid, orderid order by tranline) cumqty
LISTAGG (tranline) within group (order by tranid, itemid, orderid, tranline) OVER (partition by tranid, itemid, orderid)
FROM table
ich feststellen, dass es immer einen vollen agg kehrt anstelle eines kumulativen agg:
TranID TranLine ItemId OrderID Dollars Quantity CumDollar CumQty ListAgg
------ -------- ------ ------- ------- -------- -------- ------ -------
1 101 23845 23 2.99 1 2.99 1 101;102;103;104;105
1 102 23845 23 2.99 1 5.98 2 101;102;103;104;105
1 103 23845 23 2.99 1 8.97 3 101;102;103;104;105
1 104 23845 23 2.99 1 11.96 4 101;102;103;104;105
1 105 23845 23 2.99 1 14.95 5 101;102;103;104;105
So dies nicht sinnvoll ist.
Ich würde viel lieber dies in SQL tun, wenn überhaupt möglich. Ich bin mir bewusst, dass ich dies mit Cursors & prozedurale Logik tun kann.
Gibt es eine Möglichkeit, Windowing mit der analytischen LISTAGG-Funktion, oder vielleicht eine andere analytische Funktion, die dies unterstützen würde?
Ich bin auf 11gR2.
+1 für eine sehr gut geschriebene interessante Frage. – DCookie