Ich versuche wahrscheinlich, JOINs für Zwecke zu verwenden, die sie hier nicht beabsichtigten.Gibt es eine Möglichkeit, dass diese Abfrage mit JOINs funktioniert oder muss ich eine UNION verwenden?
Hier ist meine (vereinfacht) Tabellenstruktur:
Tabelle A
- ID
- Tabelle C ID
- IsStatic (Bit)
Tabelle B
- ID
- Tabelle A-ID (nullable)
- Tabelle C ID
Tabelle C
- ID
Mein Ziel ist es verbunden alle Tabelle B Zeilen zu erhalten Tabelle A Zeilen, in denen die Tabelle A ID-Spalte von Tabelle B einen Wert hat und dem ID-Spaltenwert von Tabelle A entspricht.
Ich brauche auch alle Tabelle B Zeilen, wo Tabelle B's Tabelle A ID Spalte keinen Wert hat.
Ich brauche auch alle Tabelle A Zeilen mit keine verbunde Tabelle B Zeilen und Tabelle Isstatic Spalte ist wahr.
Tabelle C muss auch mit Tabelle A oder Tabelle B verknüpft sein. Wenn Tabelle B keinen Wert für TableAID aufweist, sollte der Wert für TableCID dem ID-Wert von TableC entsprechen. Andernfalls sollte TableAs TableCID dem ID-Wert von TableC entsprechen.
Hier einige SQL einige TABLE-Variablen zu erstellen und mit Beispieldaten füllen:
DECLARE @TableA TABLE (TableAID int, TableCID int, IsStatic bit)
DECLARE @TableB TABLE (TableBID int, TableAID int, TableCID int)
DECLARE @TableC TABLE (TableCID int)
INSERT INTO @TableC (TableCID) VALUES (1)
INSERT INTO @TableC (TableCID) VALUES (2)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (1, 1, 0)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (2, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (3, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (4, 2, 0)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (1, NULL, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (2, 1, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (3, 2, 2)
Hier ist meine (vereinfacht) Abfrage, die nicht ganz funktioniert hat:
SELECT
a.TableAID,
b.TableBID
FROM @TableC c
LEFT OUTER JOIN @TableB b ON
(b.TableAID IS NOT NULL OR (b.TableAID IS NULL AND b.TableCID = c.TableCID))
LEFT OUTER JOIN @TableA a ON
a.TableCID = c.TableCID
AND ((a.IsStatic = 1 AND b.TableBID IS NULL)
OR (b.TableBID IS NOT NULL AND b.TableAID = a.TableAID))
Das Ergebnis dieser Abfrage das Sampel Daten ist:
TableAID TableBID
-----------------
NULL 1
1 2
NULL 3 (not required)
NULL 2 (not required)
2 3
das erforderliche Ergebnis ist:
TableAID TableBID
-----------------
NULL 1
3 NULL (missing)
2 3
1 2
Problem mit dieser Abfrage ist, dass wenn TableB.TableAID keinen Wert hat dann die Tabelle A Zeilen, in denen TableA.IsStatic ohne passende TableB Reihen wahr sind nie enthalten. Außerdem sind einige TableB-Zeilen enthalten, die nicht enthalten sein sollten.
Der einzige andere Weg, den ich sehen kann, ist mit einer union
mit einer not exists
, aber ich hatte gehofft, dies auf eine effizientere Weise zu tun.
Aktualisierung: Das Hinzufügen einer WHERE-Klausel entfernt die Zeilen "not required", lässt aber die fehlende Zeile immer noch aus.
WHERE (b.TableBID IS NULL OR b.TableAID IS NULL OR b.TableAID = a.TableAID)
Das Ergebnis der gleichen Abfrage mit der where-Klausel ist:
TableAID TableBID
-----------------
NULL 1
1 2
2 3
In Ihrem Joins versuchen Sie dies stattdessen. JOIN-Tabelle ON ISNULL (table.column, '') = ISNULL (otherTable.column, ''). Vergib mir meine Formatierung. Ich bin auf meinem Handy. – scsimon
Joins dienen zum Kombinieren von Spalten in einer einzelnen Zeile. Sie versuchen, Zeilen zu einer einzigen Ergebnismenge zusammenzufassen. Dafür sind Gewerkschaften da. Ihre Abfrage wird einfacher zu verwalten und zu verstehen sein, wenn Sie nur eine Union verwenden. Gibt es einen Grund, warum du es vermeiden willst? –
@MikeD. - Angst vor Engagement! (Witze ... Union, verstehst du?) Im Ernst, ich dachte, ich müsste ein ineffizientes "nicht vorhanden" in der Abfrage haben, die ich vermeiden wollte. Aber Antons Antwort vermeidet das und ich sehe nur, ob das für mich funktioniert. – johna