Entschuldigung für den schlechten Titel, ich war mir nicht sicher, was ein guter Titel dafür sein würde.
Dies sind derzeit (vereinfachte Ansicht der) Daten, mit denen ich arbeite
Agent | Commission
---------|------------
Smith | 100
Neo | 200
Morpheus | 300
Ich muss den Prozentsatz der gesamten Provision berechnen, für den jeder Agent verantwortlich ist.
Für Agent Smith würde der Prozentsatz also wie folgt berechnet werden (Agent Smith's commission / Sum(commission)*100
Meine erwarteten Daten wären also
Agent | Commission | % Commission
---------|---------------|---------------
Smith | 100 | 17
Neo | 200 | 33
Morpheus | 300 | 50
Ich habe eine Funktion, die die Provision für jeden Agenten zurückgibt. Ich habe eine andere Funktion, die den Prozentsatz als zurückgibt (Commission/Sum(Commission))*100
. Das Problem ist, dass dies Sum(commission)
für jede einzelne Zeile berechnet wird. Angesichts der Tatsache, dass diese Abfrage in einem Data Warehouse ausgeführt würde, wäre der Datensatz ziemlich umfangreich (derzeit sind es knapp 2000 Datensätze) und ganz ehrlich, ein schlechter Ansatz (IMO) ).
Gibt es eine Möglichkeit, das Sum(Commission)
nicht für jede abgerufene Zeile berechnen zu lassen?
Ich dachte etwas in den Zeilen einer zweiteiligen Abfrage, der erste Teil würde das sum(commission)
in eine Paketvariable / -typ holen und der zweite Teil würde sich auf diesen vorberechneten Wert beziehen, aber ich bin nicht sicher, wie ich dies erreichen kann.
Ich kann nur SQL verwenden und arbeite mit Oracle 10g R2.
quelle
Antworten:
Sie suchen nach dem
analytical function
ratio_to_reportquelle
Um alle Agenten mit ihren Provisionen und Provisionsprozentsätzen zurückzugeben, verwenden Sie eine Analysefunktion ohne Analyseklausel, sodass sich die Partition über die gesamte Tabelle erstreckt:
Wie ich von René Nyffenegger (+1) gelernt habe, verschärft die ratio_to_report-Funktion diese Syntax.
Die Verwendung eines Pakets zum Speichern der Provisionssumme würde PL / SQL umfassen, das Sie ausdrücklich ausgeschlossen haben, indem Sie angegeben haben, dass Sie eine SQL-Lösung wünschen. Da Sie jedoch bereits Funktionen verwenden, gehe ich davon aus, dass Sie PL / SQL nicht ausschließen wollten. In diesem Fall kann die Paketlösung hilfreich sein, hängt jedoch davon ab, wie Ihre Anwendung funktioniert.
Wenn Ihre Sitzung zum ersten Mal erstellt wird und die Funktion im Paket aufruft, um die Provision zu erhalten, wird implizit der Paketkonstruktor aufgerufen, der die Summe abrufen und speichern kann. Dann könnten Sie die gespeicherte Summe in Ihrer Funktion "Provision erhalten" referenzieren und sie müsste nur einmal ausgeführt werden. Sobald Sie die Funktion aus einer anderen Sitzung aufrufen, wird die Summe natürlich erneut berechnet. Das Aufrufen der Funktion für jeden Agenten ist außerdem erheblich weniger effizient als das Aufrufen einer SQL-Anweisung für alle Agenten, wenn Ihre Anwendung auf diese Weise entworfen werden kann.
Möglicherweise möchten Sie Ihre Funktion in eine Prozedur verwandeln, die einen Cursor für die obige Abfrage zurückgibt, oder eine Funktion, die die Ergebnisse der Abfrage als Ergebnismenge in Form einer Pipeline zurückgibt.
Beispieldaten:
quelle
Sie könnten die folgende Abfrage versuchen, Summe (Provision) wird nur einmal berechnet:
quelle
quelle