AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Syntaxanfrage

Ein Thema von p80286 · begonnen am 15. Aug 2016 · letzter Beitrag vom 15. Aug 2016
Antwort Antwort
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#1

Syntaxanfrage

  Alt 15. Aug 2016, 11:53
Datenbank: oracle • Version: 11 • Zugriff über: egal
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:

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<>'Aand bucnt.bu<>'Band bucnt.bu<>'L') or bucnt.bu is null)
     ) on 1=1
  )
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.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Syntaxanfrage

  Alt 15. Aug 2016, 12:30
Klingt nach Pivot (Kreuztabelle).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#3

AW: Syntaxanfrage

  Alt 15. Aug 2016, 12:58
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:
select 0 a_c, 0 k_c,0 w_c,0 misc_c from dual ------- einmal Basisdaten bitte
union
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.
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:
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
)
(Hoffentlich hab' ich da jetzt nix wesentliches übersehen.)

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"

Geändert von nahpets (15. Aug 2016 um 13:25 Uhr) Grund: Noch was nachgeschoben, zu früh abgeschickt.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#4

AW: Syntaxanfrage

  Alt 15. Aug 2016, 13:38
"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:
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
(mit 'ohne' old school cross join kriterien)
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Syntaxanfrage

  Alt 15. Aug 2016, 17:21
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:
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 'ErfMeldas Topic,A,B,L,Sonstige from bucnt pivot(sum(cnt) for (bu) in ('Aas A,'Bas B,'Las L,'sonstigeas Sonstige))
(Ist etwas anders als die erste Abfrage, aber das Prinzip ist das gleiche)

@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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#6

AW: Syntaxanfrage

  Alt 15. Aug 2016, 18:36
SQL-Code:
and cases.casereference not like 'TE%'
and cases.casereference like 'PT%'
Das versteh' ich nicht, wenn etwas like PT% ist, ist es doch zwingend nicht like TE%.

Kann man sich da die erste Zeile nicht sparen?
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Syntaxanfrage

  Alt 15. Aug 2016, 21:44
Korrekt, das ist noch ein Überbleibsel aus der Entwicklung.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz