![]() |
Datenbank: oracle • Version: 11 • Zugriff über: egal
Syntaxanfrage
Hallo zusammen,
nac einiger Zeit muß ich mich um eine Abfrage kümmern, deren Details ich nicht ganz verstehe, bzw. Ich schaff es nicht das richtige Stichwort für die Suche in Oracle zu finden
SQL-Code:
das Ergebnis des ersten selects ist ein 4-Zeiler, der mit den beiden full outer joins zu einem Dreizeiler mit 4 Spalten wird. Und genau da steh ich mir selbst auf der Leitung. Warum funktioniert das so und nicht anders.with bucnt as ( select count(cases.casekey) cnt,substr(v_mk.busunit,1,1) bu from cases join v_event on (cases.casekey=v_event.casekey and V_Event.Eventcode='IDR') left join v_mk on (cases.casekey=v_mk.casekey) where 1=1 and Cases.CaseTypeKey=5 -- ErfiMeldung and v_event.Eventdate >= add_months( to_date(to_char(trunc(sysdate),'YYYYMM')||'01','YYYYMMDD'),-1) and v_event.Eventdate< to_date(to_char(trunc(sysdate),'YYYYMM')||'01','YYYYMMDD') and cases.casereference like 'DS%' group by substr(v_mk.busunit,1,1) ) select max(a_c) DEM_SummeA ,max(k_c) DEM_SummeK ,max(w_c) DEM_SummeW ,max(misc_c) DEM_Summe_ ,max(a_c)+max(k_c)+max(w_c)+max(misc_c) DEM_Summe from (select 0 a_c, 0 k_c,0 w_c,0 misc_c from dual ------- einmal Basisdaten bitte union select a_c,k_c,w_c,misc_c from (select nvl(bucnt.cnt,0) a_c,0 w_c, 0 Misc_c from bucnt where bucnt.bu='A' ) full outer join (select nvl(cnt,0) k_c from bucnt where bucnt.bu='B' ) on 1=1 union select a_c,k_c,w_c,misc_c from (select nvl(cnt,0) w_c,0 k_c,0 a_c from bucnt where bucnt.bu='L' ) full outer join (select cnt misc_c from bucnt where ((bucnt.bu<>'A' and bucnt.bu<>'B' and bucnt.bu<>'L') or bucnt.bu is null) ) on 1=1 ) Gruß K-H |
AW: Syntaxanfrage
Klingt nach Pivot (Kreuztabelle).
|
AW: Syntaxanfrage
Wenn ich die Aufgabenstellung richtig verstehe, geht es doch darum, mehrere nacheinander ermittelte Werte aus einer Tabelle im Ergebnis nebeneinander darzustellen.
Insgesamt erscheint mir das Statement sehr komplex, so dass ich nicht nachvollziehen kann, warum das so und nicht anders gelöst wurde. Als erstes würd' ich mal diese beiden Zeilen wegwerfen, sie sind überflüssig:
SQL-Code:
Durch das Max() gehen die Werte verloren, es sei denn, im "Rest" kämen nur negative Werte vor, dann blieben die Nullen als Maximalwerte übrig.
select 0 a_c, 0 k_c,0 w_c,0 misc_c from dual ------- einmal Basisdaten bitte
union Es könnte eventuell auch sein, dass das erforderlich ist, sofern der "Rest" eine leere Ergebnismenge liefert. Wäre das im Rahmen des Möglichen? (Edit: Aber das müsste das NVL doch eigentlich verhindern? Oder?) Den Teil, in dem die Maximalwerte ermittelt werden, würd' ich so schreiben:
SQL-Code:
(Hoffentlich hab' ich da jetzt nix wesentliches übersehen.)
select max(a_c) DEM_SummeA
,max(k_c) DEM_SummeK ,max(w_c) DEM_SummeW ,max(misc_c) DEM_Summe_ ,max(a_c)+max(k_c)+max(w_c)+max(misc_c) DEM_Summe from ( select nvl(cnt,0) a_c, 0 w_c, 0 k_c, 0 Misc_c from bucnt where bu='A' union all select 0 a_c, 0 w_c, nvl(cnt,0) k_c, 0 Misc_c from bucnt where bu='B' union all select 0 a_c, nvl(cnt,0) w_c, 0 k_c, 0 Misc_c from bucnt where bu='L' union all select 0 a_c, 0 w_c, 0 k_c, cnt misc_c from bucnt where ((bu not in ('A','B','L')) or bu is null ) Nachtrag: Mir fällt gerade auf, dass das "full outer join" ja zu einem kartesischen Produkt führt. Man bekommt also in der Ergebnismenge alle Spalten aller Selects, ohne sie einzeln im Statement "aufführen" zu müssen. Da schreib' ich lieber ein bisserl mehr und hab' es insgesamt etwas übersichtlicher. Aber das ist dann wohl auch etwas "Geschmacksfrage" ;-) |
AW: Syntaxanfrage
"t1 full outer join t2 on 1=1" ist mit dieser Bedingung das Kreuzprodukt
wäre sinnvoller / verständlicher so zu schreiben: "t1 cross join t2" und liefert das kartesische Produkt. Früher (als oracle noch keine joins konnte) hätte man es so geschrieben (geht immer noch) "[select columns from ]t1, t2" (ohne where condition) Und ja, hier kann es nur darum gehen ein paar Zahlen nebeneinander zu bekommen. Würde man evtl. heute mit "Pivot" machen. Die Logik, warum paarweise die CNT pivotisiert werden, finde ich so auch nicht zu verstehen. Vielleicht ginge auch sowas in der Art, weil lauter Summen aus 0 und einem Wert dann auch nur den gleichen Wert ergeben und das Statement vielleicht eine Mischung aus Unwissenheit, früher standen da noch andere Werte-die wir nich mehr brauchen- und Migration aus einer anderen DB ist.
Code:
(mit 'ohne' old school cross join kriterien)
select a_c,k_c,w_c,misc_c from
(Select max(..cnt) as a_c from bucnt where having bu='A' group by ... ) a, (Select max(..cnt) as k_c from bucnt where having bu='B' group by ... ) b, (Select max(..cnt) as w_c from bucnt where having bu='L' group by ... ) c, (Select max(..cnt) as misc_c from bucnt where having bu!='L' and ... group by ... ) d |
AW: Syntaxanfrage
Vielen Dank für die vielen Antworten.
Zunächst einmal, PIVOT war ein gutes Stichwort ich hab eine der vorhandenen Abfragen mal umgestellt, jetzt ist es etwas übersichtlicher:
SQL-Code:
(Ist etwas anders als die erste Abfrage, aber das Prinzip ist das gleiche)
with bucnt as
( select count(v_lebfam.casekey) cnt ,decode(substr(v_mk.Busunit,1,1),'T','A','L','L','B','B','A','A','sonstige') bu from v_lebfam,v_MK ,(select distinct familykey from cases join caseevent on (cases.casekey=caseevent.casekey and eventkey=25) --Grant where cases.casetypekey=1 and cases.casereference not like 'TE%' and cases.casereference like 'PT%' and not exists(select * from caseevent e where e.casekey=cases.casekey and e.eventkey=30) -- ABD and not exists(select * from caseevent e where e.casekey=cases.casekey and e.eventkey=50 and e.eventdate is not null) -- ABD ) erteilt where v_lebfam.casekey=v_MK.casekey(+) and v_lebfam.casekey=erteilt.familykey group by decode(substr(v_mk.Busunit,1,1),'T','A','L','L','B','B','A','A','sonstige') ) select 'ErfMeld' as Topic,A,B,L,Sonstige from bucnt pivot(sum(cnt) for (bu) in ('A' as A,'B' as B,'L' as L,'sonstige' as Sonstige)) @nahpets & @jobo Es kann vorkommen, daß es zu einem oder mehreren BU keinen Wert gibt. Wenn die entsprechende Zeile dann nicht vorhanden ist, gibt es immer noch die Basisdaten, die bei max(spalte) auf jeden Fall die 0 liefern. Mal schauen was ich aus den beiden Möglichkeiten mache, da ich auch gerne "Topic" im ersten Select unterbringen würde. Vielen Dank nochmals K-H |
AW: Syntaxanfrage
SQL-Code:
Das versteh' ich nicht, wenn etwas like PT% ist, ist es doch zwingend nicht like TE%.
and cases.casereference not like 'TE%'
and cases.casereference like 'PT%' Kann man sich da die erste Zeile nicht sparen? |
AW: Syntaxanfrage
Korrekt, das ist noch ein Überbleibsel aus der Entwicklung.
Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz