2 voneinander abhängige Datenbankabfragen miteinander kombinieren
-
Hi,
ich möchte aus einer MSSQL Datenbank Datensätze laden. Diese sieht folgendermaßen aus:ID | P | V ---+---+------ 1 | 1 | NULL 2 | 1 | 1 3 | 2 | NULL 4 | 2 | 2 5 | 3 | NULL
Jetzt möchte ich bestimmte Vs laden, wobei jedes P genau einmal vorkommen soll:
SELECT * FROM db WHERE V=1 OR V=2
Da es von P=3 keine Werte zu diesen Vs gibt, möchte ich davon den "Defaultwert" mit V IS NULL haben.
SELECT * FROM db WHERE V=1 OR V=2 UNION SELECT * FROM db WHERE V IS NULL
Jetzt hab ich zwar alle Ps drin, aber eben von P=1 und P=2 die einträge mit und ohne V.
Gibt es eine Möglichkeit, in der zweiten Abfrage nur die Ps abzufragen, die in der ersten Abfrage nicht enthalten waren? Bzw umgekehrt die Ps auszuschließen, die in der ersten Abfrag bereits vorkamen?
Es würde mir auch schon helfen, wenn ich das Resultset aus einer Abfrage als WHERE-Bedingung in einer zweiten Abfrage verwenden könnte.
-
Ich hab grad was gefunden:
SELECT * FROM db WHERE V=2 OR V=3 UNION SELECT * FROM db WHERE V IS NULL AND P NOT IN (SELECT P FROM db WHERE V=2 or V=3)
Aber da der zweite Select befehl bis auf das Sternchen dem ersten entspricht, kann ich da nicht auch das Resultset vom ersten verwenden?
-
Ich weiß jetzt nicht, was es alles für Datenkonstellationen gibt, aber wie wäre es mit
SELECT df.dw_id AS ID , df.dw_p AS P , df.dw_v AS V FROM defaultwerte AS df LEFT JOIN ( SELECT dw_id , dw_p , dw_v FROM defaultwerte WHERE dw_v IS NOT NULL ) sub ON sub.dw_p = df.dw_p WHERE sub.dw_id IS NULL OR df.dw_v IS NOT NULL
oder noch etwas komprimierter
SELECT df.dw_id AS ID , df.dw_p AS P , df.dw_v AS V FROM defaultwerte AS df LEFT JOIN defaultwerte AS sub ON sub.dw_p = df.dw_p AND sub.dw_v IS NOT NULL WHERE sub.dw_id IS NULL OR df.dw_v IS NOT NULL
-
Hm, ein Join würde die Daten ja horrizontal anhängen, ich benötige sie aber vertikal, darum union. Seh da im Moment keine Möglichkeit, das mit nem Join hinzubekommen...
-
Bevor ich jetzt alles erkläre, frag ich erstmal, was du als Ergebnis mit meiner Lösung herausbekommst
und was noch falsch ist ... ich habe nur deine 5 Anfangsdatensätze
-
Das Ergebnis ist genau richtig. Das einzige, was ich ändern möchten würde ist, dass in dem Query nur noch ein SELECT steht. Also so wie:
SELECT * FROM Test WHERE V=1 OR V=2 UNION SELECT * FROM Test WHERE V IS NULL AND P NOT IN Test.P
Nur noch Kosmetik...
-
Für was auch immer das gut sein soll.... aber man kann es sich auch umständlich machen
SELECT df.dw_id AS ID , df.dw_p AS P , df.dw_v AS V FROM defaultwerte AS df WHERE df.dw_v IN (1,2) UNION SELECT df.dw_id AS ID , df.dw_p AS P , df.dw_v AS V FROM defaultwerte AS df WHERE df.dw_v IS NULL AND df.dw_p NOT IN ( SELECT df.dw_p AS P FROM defaultwerte AS df WHERE df.dw_v IN (1,2) )
Das mit dem direkten Zugriff über Test.P, wie du es schreibst, geht nicht. Da musst du auf ein Subselect zurückgreifen.
PS: einen hab ich noch
SELECT MAX(df.dw_id) AS ID , df.dw_p AS P , MAX(df.dw_v) AS V FROM defaultwerte AS df GROUP BY df.dw_p
EDIT: Wobei das mit der "MAX(df.dw_id) AS ID" eher nicht zu verwenden ist.
-
Sorry, hab mich falsch ausgedrückt: zwei Selects, auf jeder Seite vom Union eins...
-
Was soll das denn für Vorteile bringen gegenüber anderen Möglichkeiten, die einem die Datenbank zur Verfügung stellt
-
Auch die Datenbank ist nur ein Computer und muss (wie ich annehme) jedes Select verarbeiten. Wenn ich mir ein Select einfach sparen kann, ist doch prima. Funktionieren tuts so auch.
Und nochmal zur verdeutlichung:
Aktuell:SEELCT * FROM db WHERE ConditionA UNION SELECT * FROM db WHERE ConditionB AND P NOT IN (SELECT P FROM db WHERE ConditionA)
Kosmetisch aufbereited:
SEELCT * FROM db WHERE ConditionA UNION SELECT * FROM db WHERE ConditionB AND P NOT IN "Erster SELECT.P"
-
Auch die Datenbank ist nur ein Computer
und ich dachte, det wäre ne Software.
Also deine kosmetisch aufbereitete Lösung funktioniert nun mal nicht, wie schon erwähnt. Ich glaube auch nicht, das UNION dafür erfunden wurde.
Und bevor man eine Abfrage mehrfach in einer Query verwendet, kann man dies übersichtlicher gestalten und auf entsprechende JOINS zurückgreifen.Dein Threadtitel handelt schließlich von abhängigen Datenbankabfragen und da ist UNION sicher der falsche Ansatz.
Aber vielleicht werde ich ja gleich von einem Datenbankguru belehrt.