748 Stimmen

Wie wählt man alle Datensätze einer Tabelle aus, die in einer anderen Tabelle nicht existieren?

table1 (id, name)
table2 (id, name)

Abfrage:

SELECT name   
FROM table2  
-- die noch nicht in table1 vorhanden sind

0 Stimmen

Schauen Sie sich die Lösung mit UNION unten an, die um ein Vielfaches schneller ist als jede andere hier aufgeführte Lösung.

21voto

Bob Punkte 191

Hier ist, was für mich am besten funktioniert hat.

SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID

Dies war mehr als doppelt so schnell wie jede andere Methode, die ich ausprobiert habe.

0 Stimmen

Vielen Dank, das funktioniert auch gut mit einer großen Menge an Daten! Aber ich frage mich nur über den Begriff "Außer" nach.

0 Stimmen

767ms für mich bei 5k Datensätzen von insgesamt 200k Datensätzen. Alles andere hat Minuten gedauert.

0 Stimmen

18voto

user4872693 Punkte 171

Pass auf mögliche Fallen auf. Wenn das Feld Name in Tabelle1 Nullwerte enthält, wirst du überrascht sein. Besser ist:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT COALESCE(name ,'')
     FROM table1)

2 Stimmen

COALESCE > ISNULL (ISNULL ist eine nutzlose T-SQL-Ergänzung zur Sprache, die nichts Neues oder Besseres als COALESCE tut)

10voto

Izzy Punkte 1605

Sie können EXCEPT in mssql oder MINUS in Oracle verwenden, sie sind identisch gemäß :

http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/

8voto

David Fawzy Punkte 1016

Dies funktioniert gut für mich

SELECT * 
FROM [dbo].[Tabelle1] t1
LEFT JOIN [dbo].[Tabelle2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL

5voto

fede72bari Punkte 156

Alle oben genannten Abfragen sind auf großen Tabellen unglaublich langsam. Ein Strategiewechsel ist erforderlich. Hier ist der Code, den ich für eine meiner Datenbanken verwendet habe. Sie können ihn transliterieren, indem Sie die Felder und Tabellennamen ändern.

Das ist die Strategie: Sie erstellen zwei implizite temporäre Tabellen und machen eine Union derselben.

  1. Die erste temporäre Tabelle stammt aus einer Auswahl aller Zeilen der ersten Originaltabelle, deren Felder Sie kontrollieren möchten, die jedoch nicht in der zweiten Originaltabelle vorhanden sind.
  2. Die zweite implizite temporäre Tabelle enthält alle Zeilen der beiden Originaltabellen, die übereinstimmende Werte der Spalte/des Feldes haben, das Sie kontrollieren möchten.
  3. Das Ergebnis der Union ist eine Tabelle, die mehr als eine Zeile mit demselben Kontrollfeldwert hat, wenn dieser Wert in den beiden Originaltabellen übereinstimmt (einer kommt aus der ersten Auswahl, der andere aus der zweiten Auswahl), und nur eine Zeile mit dem Kontrollspaltenwert, wenn der Wert der ersten Originaltabelle mit keinem Wert der zweiten Originaltabelle übereinstimmt.
  4. Sie gruppieren und zählen. Wenn die Anzahl 1 beträgt, gibt es keine Übereinstimmung, und schließlich wählen Sie nur die Zeilen mit der Anzahl gleich 1 aus.

Sieht nicht elegant aus, aber es ist um Größenordnungen schneller als alle oben genannten Lösungen.

WICHTIGE ANMERKUNG: Aktivieren Sie den INDEX für die zu überprüfenden Spalten.

SELECT name, source, id
FROM 
(
    SELECT name, "active_ingredients" as source, active_ingredients.id as id 
        FROM active_ingredients

    UNION ALL

    SELECT active_ingredients.name as name, "UNII_database" as source, temp_active_ingredients_aliases.id as id 
    FROM active_ingredients
    INNER JOIN temp_active_ingredients_aliases ON temp_active_ingredients_aliases.alias_name = active_ingredients.name

) tbl
GROUP BY name
HAVING count(*) = 1
ORDER BY name

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X