Database
 sql >> Datenbank >  >> RDS >> Database

T-SQL SET-Operatoren Teil 2:INTERSECT und EXCEPT

In meinem vorherigen Artikel habe ich die Grundlagen von Mengenoperatoren, ihre Typen und Voraussetzungen für ihre Verwendung erklärt. Ich habe auch über UNION- und UNION ALL-Operatoren, ihre Verwendung und Unterschiede gesprochen.

In diesem Artikel lernen wir Folgendes:

  1. EXCEPT- und INTERSECT-Operatoren.
  2. Unterschied zwischen INTERSECT und INNER JOIN.
  3. Die ausführliche Erklärung von INTERSECT und EXCEPT mit einem Beispiel.

Die Operatoren EXCEPT und INTERSECT wurden in SQL Server 2005 eingeführt. Beide sind Mengenoperatoren, die verwendet werden, um die von zwei Abfragen generierten Ergebnismengen zu kombinieren und die gewünschte Ausgabe abzurufen.

Was ist der INTERSECT-Operator

INTERSECT wird verwendet, um Datensätze zu erhalten, die allen Datensätzen gemeinsam sind, die aus mehreren Abfragen oder Tabellen abgerufen wurden. Hier ist eine Visualisierung davon:

Die Syntax des INTERSECT-Operators lautet wie folgt:

SELECT COLUMN1, 
       COLUMN2, 
       COLUMN3, 
       COLUMN4..FROM TABLE1 
INTERSECT
SELECT COLUMN1, 
       COLUMN2, 
       COLUMN3, 
       COLUMN4..FROM TABLE2

Was ist der EXCEPT-Operator

EXCEPT wird verwendet, um Datensätze abzurufen, die in einer Abfrage, aber nicht in einer anderen Abfrage gefunden werden. Mit anderen Worten, es gibt Datensätze zurück, die für eine Ergebnismenge eindeutig sind. So sieht es visualisiert aus:

Die Syntax des EXCEPT-Operators lautet wie folgt:

SELECT COLUMN1, 
       COLUMN2, 
       COLUMN3, 
       COLUMN4..FROM TABLE1 
EXCEPT
SELECT COLUMN1, 
       COLUMN2, 
       COLUMN3, 
       COLUMN4..FROM TABLE2

Lassen Sie uns ein Demo-Setup erstellen, um zu demonstrieren, wie diese Operatoren verwendet werden können.

Demo-Setup

Um INTERSECT und EXCEPT zu demonstrieren, habe ich zwei Tabellen namens Employee erstellt und Praktikant .

Führen Sie die folgende Abfrage aus, um diese Tabellen zu erstellen:

CREATE TABLE [DBO].[EMPLOYEE] 
  ( 
     [NAME]             [NVARCHAR](250) NOT NULL, 
     [BUSINESSENTITYID] [INT] NOT NULL, 
     [NATIONALIDNUMBER] [NVARCHAR](15) NOT NULL, 
     [LOGINID]          [NVARCHAR](256) NOT NULL, 
     [BIRTHDATE]        [DATE] NOT NULL, 
     [MARITALSTATUS]    [NCHAR](1) NOT NULL, 
     [GENDER]           [NCHAR](1) NOT NULL 
  ) 
ON [PRIMARY] 

CREATE TABLE [DBO].[TRAINEE] 
  ( 
     [NAME]             [NVARCHAR](250) NOT NULL, 
     [BUSINESSENTITYID] [INT] NOT NULL, 
     [NATIONALIDNUMBER] [NVARCHAR](15) NOT NULL, 
     [BIRTHDATE]        [DATE] NOT NULL, 
     [GENDER]           [NCHAR](1) NOT NULL 
  ) 
ON [PRIMARY]

Lassen Sie uns nun einige Dummy-Daten in Employee einfügen Tabelle, indem Sie die folgende Abfrage ausführen:

INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'KEN SÁNCHEZ', 1, N'295847284', N'ADVENTURE-WORKS\KEN0', CAST(N'1969-01-29' AS DATE), N'S', N'M')
GO
INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'TERRI DUFFY', 2, N'245797967', N'ADVENTURE-WORKS\TERRI0', CAST(N'1971-08-01' AS DATE), N'S', N'F')
GO
INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'ROBERTO TAMBURELLO', 3, N'509647174', N'ADVENTURE-WORKS\ROBERTO0', CAST(N'1974-11-12' AS DATE), N'M', N'M')
GO
INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'ROB WALTERS', 4, N'112457891', N'ADVENTURE-WORKS\ROB0', CAST(N'1974-12-23' AS DATE), N'S', N'M')
GO
INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'GAIL ERICKSON', 5, N'695256908', N'ADVENTURE-WORKS\GAIL0', CAST(N'1952-09-27' AS DATE), N'M', N'F')
GO
INSERT [DBO].[EMPLOYEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [LOGINID], [BIRTHDATE], [MARITALSTATUS], [GENDER]) VALUES (N'JOSSEF GOLDBERG', 6, N'998320692', N'ADVENTURE-WORKS\JOSSEF0', CAST(N'1959-03-11' AS DATE), N'M', N'M')

Als Nächstes machen wir dasselbe für den Trainee Tabelle:

INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'JOHN WOOD', 18, N'222969461', CAST(N'1978-03-06' AS DATE), N'M')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'MARY DEMPSEY', 19, N'52541318', CAST(N'1978-01-29' AS DATE), N'F')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'WANIDA BENSHOOF', 20, N'323403273', CAST(N'1975-03-17' AS DATE), N'F')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'KEN SÁNCHEZ', 1, N'295847284', CAST(N'1969-01-29' AS DATE), N'M')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'TERRI DUFFY', 2, N'245797967', CAST(N'1971-08-01' AS DATE),  N'F')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'ROBERTO TAMBURELLO', 3, N'509647174', CAST(N'1974-11-12' AS DATE), N'M')
GO

Lassen Sie uns nun INTERSECT verwenden, um die Liste der Mitarbeiter abzurufen, die beiden Tabellen gemeinsam sind. Führen Sie dazu die folgende Abfrage aus:

SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   EMPLOYEE 
INTERSECT 
SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   TRAINEE

Die Ausgabe dieser Abfrage sollte wie folgt aussehen:

Wie Sie im obigen Screenshot sehen können, hat die Abfrage nur Datensätze zurückgegeben, die beiden Tabellen gemeinsam sind.

INNER JOIN vs. INTERSECT

In den meisten Fällen geben INTERSECT und INNER JOIN dieselbe Ausgabe zurück, es gibt jedoch einige Ausnahmen. Ein einfaches Beispiel wird uns helfen, dies zu verstehen.

Fügen wir der Trainee-Tabelle einige doppelte Datensätze hinzu. Führen Sie die folgende Abfrage aus:

INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'TERRI DUFFY', 2, N'245797967', CAST(N'1971-08-01' AS DATE),  N'F')
GO
INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (N'ROBERTO TAMBURELLO', 3, N'509647174', CAST(N'1974-11-12' AS DATE), N'M')
GO

Jetzt versuchen wir, die gewünschte Ausgabe mit INTERSECT zu generieren.

SELECT NAME,BUSINESSENTITYID,NATIONALIDNUMBER,BIRTHDATE,GENDER FROM EMPLOYEE
INTERSECT
SELECT NAME,BUSINESSENTITYID,NATIONALIDNUMBER,BIRTHDATE,GENDER FROM TRAINEE

Dies ist die Ausgabe, die wir erhalten:

Versuchen wir es jetzt mit INNER JOIN.

SELECT A.NAME, 
       A.BUSINESSENTITYID, 
       A.NATIONALIDNUMBER, 
       A.BIRTHDATE, 
       A.GENDER 
FROM   EMPLOYEE A 
       INNER JOIN TRAINEE B 
               ON A.NAME = B.NAME

Die Ausgabe, die wir in diesem Fall erhalten, ist wie folgt:

Wie Sie auf dem obigen Screenshot sehen können, ruft INNER JOIN nun Datensätze ab, die beiden Tabellen gemeinsam sind. Es füllt alle Datensätze aus der rechten Tabelle. Daher können Sie doppelte Datensätze sehen.

Nun fügen wir das Schlüsselwort DISTINCT zur INNER JOIN-Abfrage hinzu und sehen uns an, was das bewirkt:

SELECT DISTINCT A.NAME, 
                A.BUSINESSENTITYID, 
                A.NATIONALIDNUMBER, 
                A.BIRTHDATE, 
                A.GENDER 
FROM   EMPLOYEE A 
       INNER JOIN TRAINEE B 
               ON A.NAME = B.NAME

Die Ausgabe sollte so aussehen:

Wie Sie auf dem obigen Screenshot sehen können, wurden doppelte Datensätze eliminiert.

INTERSECT und INNER JOIN behandeln NULL-Werte unterschiedlich. Bei INNER JOIN sind zwei NULL-Werte unterschiedlich, daher besteht die Möglichkeit, dass sie beim Verbinden zweier Tabellen übersprungen werden.

Andererseits behandelt INTERSECT zwei NULL-Werte als gleich, sodass Datensätze mit NULL-Werten nicht eliminiert werden. Um es besser zu verstehen, sehen wir uns ein Beispiel an.

Zuerst fügen wir dem Trainee einige NULL-Werte hinzu und Mitarbeiter Tabellen, indem Sie die folgende Abfrage ausführen:

INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) VALUES (NULL, 3, N'509647174', CAST(N'1974-11-12' AS DATE), N'M')
GO

INSERT [DBO].[Employee] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER],[LOGINID], [BIRTHDATE],[MARITALSTATUS], [GENDER]) VALUES (NULL, 3, N'509647174','ADVENTURE-WORKS\TERRI0', CAST(N'1974-11-12' AS DATE),  N'M',N'M')
GO

Versuchen wir nun, Datensätze abzurufen, die den beiden Tabellen gemeinsam sind, indem wir INTERSECT und INNER JOIN verwenden. Sie müssen die folgende Abfrage ausführen:

/*QUERY WITH INTERSECT*/ 
SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   EMPLOYEE 
INTERSECT 
SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   TRAINEE 

/*QUERY WITH INNER JOIN*/ 
SELECT A.NAME, 
       A.BUSINESSENTITYID, 
       A.NATIONALIDNUMBER, 
       A.BIRTHDATE, 
       A.GENDER 
FROM   EMPLOYEE A 
       INNER JOIN TRAINEE B 
               ON A.NAME = B.NAME

Dies ist die Ausgabe, die wir als Ergebnis erhalten sollten:

Wie Sie oben sehen können, enthält die von INTERSECT generierte Ergebnismenge NULL-Werte, während INNER JOIN die Datensätze mit NULL-Werten überspringt.

Der EXCEPT-Operator

Sehen wir uns einen Anwendungsfall an, um den EXCEPT-Operator in Aktion zu demonstrieren. Ich möchte beispielsweise die Details weiblicher Mitarbeiter aus der Mitarbeitertabelle ausfüllen. Die folgende Abfrage hilft uns dabei:

SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   EMPLOYEE 
WHERE  GENDER = 'F' 
EXCEPT 
SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   EMPLOYEE 
WHERE  GENDER = 'M'

Dies ist die Ausgabe, die wir erhalten:

Wie Sie oben sehen können, füllte die Abfrage nur die Details der weiblichen Mitarbeiter aus.

Sie können die Ergebnismenge auch mit einer Unterabfrage füllen:

SELECT NAME, 
       BUSINESSENTITYID, 
       NATIONALIDNUMBER, 
       BIRTHDATE, 
       GENDER 
FROM   EMPLOYEE AS M 
WHERE  GENDER = 'F' 
       AND GENDER NOT IN (SELECT GENDER 
                          FROM   EMPLOYEE AS F 
                          WHERE  GENDER = 'M')

Einschränkungen von INTERSECT und EXCEPT

  1. Wir können EXCEPT und INTERSECT nicht in verteilten partitionierten Ansichtsdefinitionen mit COMPUTE- und COMPUTE BY-Klauseln verwenden.
  2. EXCEPT und INTERSECT können in Nur-Schnellvorlauf- und statischen Cursorn verwendet werden.
  3. EXCEPT und INTERSECT können in verteilten Abfragen verwendet, aber nur auf dem lokalen Server ausgeführt werden. Sie können sie nicht auf einem entfernten Server ausführen.

Zusammenfassung

In diesem Artikel habe ich behandelt:

  1. Die Operatoren EXCEPT und INTERSECT.
  2. Der Unterschied zwischen INTERSECT und INNER JOIN.
  3. Eine ausführliche Erklärung der INTERSECT- und EXCEPT-Operatoren mit einem Beispiel.