WARNUNG ZU LÖSUNGEN:
VIELE BESTEHENDE LÖSUNGEN GEBEN DIE FALSCHE AUSGABE, WENN REIHEN NICHT EINZIGARTIG SIND
Wenn Sie die einzige Person sind, die Tabellen erstellt, ist dies möglicherweise nicht relevant. Mehrere Lösungen geben jedoch eine andere Anzahl von Ausgabezeilen als der betreffende Code an, wenn eine der Tabellen möglicherweise keine eindeutigen Zeilen enthält.
WARNUNG ÜBER DIE PROBLEMSTELLUNG:
IN MIT MEHREREN SPALTEN GIBT ES NICHT, DENKEN SIE SORGFÄLTIG, WAS SIE WOLLEN
Wenn ich ein In mit zwei Spalten sehe, kann ich mir vorstellen, dass es zwei Dinge bedeutet:
- Der Wert von Spalte a und Spalte b wird unabhängig voneinander in der anderen Tabelle angezeigt
- Die Werte von Spalte a und Spalte b werden in der anderen Tabelle zusammen in derselben Zeile angezeigt
Szenario 1 ist ziemlich trivial. Verwenden Sie einfach zwei IN-Anweisungen.
In Übereinstimmung mit den meisten vorhandenen Antworten gebe ich hiermit einen Überblick über die genannten und zusätzlichen Ansätze für Szenario 2 (und eine kurze Beurteilung):
EXISTS (sicher, empfohlen für SQL Server)
Wie von @mrdenny bereitgestellt, klingt EXISTS genau so, wie Sie es suchen. Hier ist sein Beispiel:
SELECT * FROM T1
WHERE EXISTS
(SELECT * FROM T2
WHERE T1.a=T2.a and T1.b=T2.b)
LEFT SEMI JOIN (Sicher, empfohlen für Dialekte, die dies unterstützen)
Dies ist eine sehr prägnante Art des Beitritts, aber leider unterstützen die meisten SQL-Dialekte, einschließlich SQL Server, dies derzeit nicht.
SELECT * FROM T1
LEFT SEMI JOIN T2 ON T1.a=T2.a and T1.b=T2.b
Mehrere IN-Anweisungen (sicher, aber Vorsicht vor Codeduplizierungen)
Wie von @cataclysm erwähnt, kann die Verwendung von zwei IN-Anweisungen ebenfalls den Trick ausführen. Vielleicht übertrifft es sogar die anderen Lösungen. Was Sie jedoch sehr vorsichtig sein sollten, ist die Codeduplizierung. Wenn Sie jemals aus einer anderen Tabelle auswählen oder die where-Anweisung ändern möchten, besteht ein erhöhtes Risiko, dass Sie Inkonsistenzen in Ihrer Logik erzeugen.
Grundlösung
SELECT * from T1
WHERE a IN (SELECT a FROM T2 WHERE something)
AND b IN (SELECT b FROM T2 WHERE something)
Lösung ohne Codeduplizierung (Ich glaube, dies funktioniert nicht in regulären SQL Server-Abfragen)
WITH mytmp AS (SELECT a, b FROM T2 WHERE something);
SELECT * from T1
WHERE a IN (SELECT a FROM mytmp)
AND b IN (SELECT b FROM mytmp)
INNER JOIN (technisch kann es sicher gemacht werden, aber oft wird dies nicht getan)
Der Grund, warum ich die Verwendung eines inneren Joins als Filter nicht empfehle, liegt darin, dass in der Praxis häufig Duplikate in der rechten Tabelle Duplikate in der linken Tabelle verursachen. Und um die Sache noch schlimmer zu machen, wird das Endergebnis manchmal deutlich, während die linke Tabelle möglicherweise nicht eindeutig sein muss (oder in den ausgewählten Spalten nicht eindeutig sein muss). Darüber hinaus haben Sie die Möglichkeit, eine Spalte auszuwählen, die in der linken Tabelle nicht vorhanden ist.
SELECT T1.* FROM T1
INNER JOIN
(SELECT DISTINCT a, b FROM T2) AS T2sub
ON T1.a=T2sub.a AND T1.b=T2sub.b
Häufigste Fehler:
- Direkter Beitritt zu T2 ohne sichere Unterabfrage. Dies führt zu einem Risiko der Vervielfältigung.
- SELECT * (Garantiert, um Spalten von T2 zu erhalten)
- SELECT c (Garantiert nicht, dass Ihre Spalte von T1 kommt und immer kommt)
- Kein DISTINCT oder DISTINCT am falschen Ort
KONKATENATION VON SPALTEN MIT SEPARATOR (Nicht sehr sichere, schreckliche Leistung)
Das Funktionsproblem besteht darin, dass es schwierig wird, sicherzustellen, dass das Ergebnis 100% genau ist, wenn Sie ein Trennzeichen verwenden, das in einer Spalte auftreten kann. Das technische Problem besteht darin, dass diese Methode häufig Typkonvertierungen durchführt und Indizes vollständig ignoriert, was zu einer möglicherweise schrecklichen Leistung führt. Trotz dieser Probleme muss ich zugeben, dass ich es manchmal immer noch für Ad-hoc-Abfragen in kleinen Datensätzen verwende.
SELECT * FROM T1
WHERE CONCAT(a,"_",b) IN
(SELECT CONCAT(a,"_",b) FROM T2)
Wenn Ihre Spalten numerisch sind, müssen Sie sie bei einigen SQL-Dialekten zuerst in Zeichenfolgen umwandeln. Ich glaube, SQL Server wird dies automatisch tun.
Zum Abschluss: Wie üblich gibt es in SQL viele Möglichkeiten, dies zu tun. Wenn Sie sichere Entscheidungen treffen, vermeiden Sie Überraschungen und sparen auf lange Sicht Zeit und Kopfzerbrechen.