Hilfe bei Abfrage (case when...)

Eine Frage zum Freitag Nachmittag hätte ich noch. In deiner Abfrage hast du eine Unterabfrage 2 eingebaut:

PHP:
SELECT
  h.id,
  u2.warp
...
...
...
FROM

LEFT JOIN (

SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery2
     ) u2
ON     h.ID = u2.ID AND u2.zeile = '1'

Im Teil ganz oben wird für die h.id der Warp-Wert u2.Warp abgefragt und ausgegeben. Angenommen, dieser Wert Warp fällt jetzt an mehreren Messoperationen an und ich möchte im oberen Teil je eine Spalte haben mit Warp_1, Warp_2 und Warp_3. Muss ich dann für jeden dieser Werte ein eigenes Unterquery erstellen oder geht das auch anders. Dabei wäre das Grundgerüst immer das Gleiche nur die Messoperation wäre unterschiedlich.

Gruß, Matthias
 
Werbung:
Das wäre möglich aber aus verschiedenen Gründen nicht sehr elegant. Vor allem aber würde es mich stören, mehrere Spalten in der Ausgabe für das gleiche Atribut zu verwenden. Und dann wäre die Anzahl vermutlich nicht fix, das wäre keine vernünftige Normalform.

Wenn eine Schreibweise wie
Spalte1=ID | Spalte2=Warp_1; Warp_2; Warp_N
auch in Frage käme würde ich im Select-Teil eine Unterabfrage machen und in dieser mit etwas wie GROUP_CONCAT alle Warp-Werte verketten.
Is there any function in oracle similar to group_concat in mysql?
Da kommt es jetzt aber wirklich drauf an welches DBMS, welche Version. Die Syntax ist überall anders.
 
Grundsätzlich könnte man auch noch etwas umstellen um den Subquery nicht mehrfach laufen zu lassen sondern "nur" mehrfach zu joinen:
Code:
WITH u2(zeile,ID,WARP) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery2 )

SELECT
  h.id,
  u2.warp
...
...
...
FROM

LEFT JOIN u2
ON  h.ID = u2.ID AND u2.zeile = '1'
LEFT JOIN u2 u3
ON  h.ID = u3.ID AND u3.zeile = '2'
LEFT JOIN u2 u4
ON  h.ID = u4.ID AND u4.zeile = '3'
 
Hallo Ukulele,

ich habe versucht, den Vorschlag von dir bei meiner Abfrage umzusetzen, bin aber bislang gescheitert.

Folgende Fragen hätte ich zu dem von dir aufgeführten Teil:

  1. Mit u2 wird die Unterabfrage benannt, richtig?
  2. Alle Spalten in Klammern u2(zeile,ID,WARP) müssen im Select-Teil aufgelistet sein, richtig? Müssen dabei auch die Bezeichnungen übereinstimmen, d.h. u2(zeile,ID,WARP) und im select-Teil zeile,ID,WARP oder geht auch zeile, w.id, adew.warp oder muss es dann zeile, w.id as id, adew.warp as warp lauten?
PHP:
WITH u2(zeile,ID,WARP) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery2 )

Ich habe es nicht geschafft, mir die 3 Spalten für Warp_1, Warp_2 und Warp_3 zu erstellen. Vielleicht kannst du mir da noch mal helfen :)

PHP:
SELECT
  h.id,
  u2.warp

FROM

LEFT JOIN u2 ON  h.ID = u2.ID AND u2.zeile = '1'
LEFT JOIN u2 u3 ON  h.ID = u3.ID AND u3.zeile = '2'
LEFT JOIN u2 u4 ON  h.ID = u4.ID AND u4.zeile = '3'

Gruß, Matthias
 
1. Ja u2 habe ich als Alias eingesetzt und unterquery2 ist die Tabelle oder der Join der eigentlich dahinter steht mit all seinen Bedingungen. Also eine verkürzte Form und dann ein Alias da drauf.

2. Also WITH ist erstmal relativ einfach von der Struktur. Mit WITH erstellst du vor dem eigentlichen SELECT (welches auf ein WITH folgen muss) soetwas wie eine oder mehrere temporäre Tabellen. Die können aus komplett unterschiedlichen Abfragen bestehen und sich auf sich selbst beziehen. Das ist aber in deinem Fall jetzt erstmal nicht relevant.

Du kannst das auch ohne Spaltenbeschriftung im WITH-Teil machen, also
Code:
 WITH t AS ( SELECT 1 AS tolle_spalte ) SELECT t.* FROM t
Die dürfen sich auch widersprechen dann gilt das hinter dem WITH
Code:
 WITH t(nicht_ganz_so_tolle_spalte) AS ( SELECT 1 AS tolle_spalte ) SELECT t.* FROM t
oder der SELECT liefert gar keine Bezeichnung, z.B. bei berechneten Spalten
Code:
 WITH t(ziemlich_tolle_spalte) AS ( SELECT 1+1 ) SELECT t.* FROM t
Natürlich muss die Anzahl der Spalten übereinstimmen.

3. Eigentlich werden auch erstmal alle Zeilen für deine Warp-Werte erstellt und dann werden die ersten drei mit drei Joins als Spalten angefügt. Die LEFT JOINs in dem gezeigten Code sind richtig, im SELECT-Teil fehlen allerdings die Spalten:
Code:
SELECT
 h.id,
 u2.warp AS warp1
u3.warp AS warp2
u4.warp AS warp3

FROM

LEFT JOIN u2 ON h.ID = u2.ID AND u2.zeile = '1'
LEFT JOIN u2 u3 ON h.ID = u3.ID AND u3.zeile = '2'
LEFT JOIN u2 u4 ON h.ID = u4.ID AND u4.zeile = '3'
 
Ich habe wieder ein wenig probiert und für mich folgendes festgestellt:

PHP:
WITH u2(zeile,ID,Wert_1,Wert_2) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,  Wert_1, Wert_2
FROM   unterquery2 )

Die Reihenfolge der Sachen in Klammern nach u2(...) muss genau mit der Reihenfolge der aufgelisteten Sachen im select-Teil übereinstimmen sonst kommt im "Haupt-Select-Teil" z.Bsp. bei u2.Wert1 Murks raus. Wenn also in Klammern u2(...) Wert_1 und Wert_2 vertauscht werden, so muss dies auch im select-Teil erfolgen. Genauso, wenn ich dies im select-Teil ändere, muss ich das bei u2(...) ebenfalls anpassen.

Bezüglich Performance dauert es sehr lange, wenn ich es so mache, wie du es mir gezeigt hast. Wenn ich allerdings eine u2, u3 und u4 erstelle und die JOINs anpasse wie im folgenden Code, geht es sehr schnell.

PHP:
WITH u2(zeile,ID,WARP) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery2 )

,u3(zeile,ID,WARP) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery3 )

,u4(zeile,ID,WARP) AS (
SELECT   ROW_NUMBER() OVER (PARTITION BY ID ORDER BY deine_spalten_oder_CASE_oder_wie_auch_immer) AS zeile,
     ID,
     WARP
FROM   unterquery3 )

select

h.id,
u2.warp AS warp1
u3.warp AS warp2
u4.warp AS warp3

FROM

LEFT JOIN u2 ON h.ID = u2.ID AND u2.zeile = '1'
LEFT JOIN u3 ON h.ID = u3.ID AND u3.zeile = '2'
LEFT JOIN u4 ON h.ID = u4.ID AND u4.zeile = '3'
 
Werbung:
Das mit der Reihenfolge liegt auf der Hand, das mit der Performance nicht. Das ist allerdings schwer so aus dem Stand zu beurteilen.
 
Zurück
Oben