sql >> Database >  >> RDS >> Database

T-SQL SET-operators Deel 2:INTERSECT en BEHALVE

In mijn vorige artikel heb ik de basisprincipes van set-operators, hun typen en vereisten voor het gebruik ervan uitgelegd. Ik heb ook gesproken over de operators UNION en UNION ALL, hun gebruik en verschillen.

In dit artikel gaan we het volgende leren:

  1. BEHALVE en INTERSECT-operators.
  2. Verschil tussen INTERSECT en INNER JOIN.
  3. De gedetailleerde uitleg van INTERSECT en BEHALVE met een voorbeeld.

EXCEPT- en INTERSECT-operatoren zijn geïntroduceerd in SQL Server 2005. Beide zijn set-operators die worden gebruikt om de resultatensets te combineren die door twee query's worden gegenereerd en om de gewenste uitvoer op te halen.

Wat is de INTERSECT-operator

INTERSECT wordt gebruikt om records op te halen die gemeenschappelijk zijn voor alle gegevenssets die zijn opgehaald uit meerdere query's of tabellen. Hier is een visualisatie hiervan:

De syntaxis van de INTERSECT-operator is als volgt:

SELECTEER KOLOM1, KOLOM2, KOLOM3, KOLOM4..UIT TABEL1 INTERSECTSELECTEER KOLOM1, KOLOM2, KOLOM3, KOLOM4..UIT TABEL2

Wat is de EXCEPT-operator

EXCEPT wordt gebruikt om records op te halen die in de ene query worden gevonden, maar niet in een andere query. Met andere woorden, het retourneert records die uniek zijn voor één resultaatset. Zo ziet het er gevisualiseerd uit:

De syntaxis van de EXCEPT-operator is als volgt:

SELECTEER KOLOM1, KOLOM2, KOLOM3, KOLOM4..UIT TABEL1 BEHALVE SELECTEER KOLOM1, KOLOM2, KOLOM3, KOLOM4..UIT TABEL2

Laten we een demo-opstelling maken om te demonstreren hoe deze operators kunnen worden gebruikt.

Demo instellen

Om INTERSECT en EXCEPT te demonstreren, heb ik twee tabellen gemaakt met de naam Employee en Stagiair .

Voer de volgende query uit om deze tabellen te maken:

TABEL MAKEN [DBO].[WERKNEMER] ( [NAAM] [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 ) OP [PRIMARY] MAAK TABEL [DBO] .[TRAINEE] ( [NAME] [NVARCHAR](250) NOT NULL, [BUSINESSENTITYID] [INT] NOT NULL, [NATIONALIDNUMBER] [NVARCHAR](15) NOT NULL, [BIRTHDATE] [DATE] NOT NULL, [GENDER] [NCHAR](1) NIET NULL ) OP [PRIMAIR]

Laten we nu wat dummy-gegevens invoegen in de Werknemer tabel door de volgende query uit te voeren:

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

Vervolgens doen we hetzelfde voor de Trainee tafel:

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

Laten we nu INTERSECT gebruiken om de lijst met werknemers op te halen die in beide tabellen voorkomen. Voer hiervoor de volgende query uit:

SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, GEBOORTEDATUM, GESLACHT VAN WERKNEMER INTERSECT SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, GEBOORTEDATUM, GESLACHT VAN STRAINER

De uitvoer van deze vraag zou als volgt moeten zijn:

Zoals je in de bovenstaande schermafbeelding kunt zien, heeft de query alleen records geretourneerd die voor beide tabellen gelden.

INNER JOIN vs. INTERSECT

In de meeste gevallen retourneren INTERSECT en INNER JOIN dezelfde uitvoer, maar er zijn enkele uitzonderingen. Een eenvoudig voorbeeld zal ons helpen dit te begrijpen.

Laten we enkele dubbele records toevoegen aan de tabel Trainee. Voer de volgende vraag uit:

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

Nu gaan we proberen de gewenste output te genereren met INTERSECT.

SELECTEER NAAM,BUSINESSENTITYID,NATIONALIDNUMBER,GEBOORTEDATUM,GENDER VAN WERKNEMERINTERSECTSELECTEER NAAM,BUSINESSENTITYID,NATIONALIDNUMBER,GEBOORTEDATUM,GENDER VAN STRAINER

Dit is de output die we krijgen:

Laten we nu INNER JOIN proberen.

SELECTEER A.NAME, A.BUSINESSENTITYID, A.NATIONALIDNUMBER, A.BIRTHDATE, A.GENDER VAN WERKNEMER A INNER WORD LID VAN TRAINEE B OP A.NAME =B.NAME

De output die we in dit geval krijgen is als volgt:

Zoals u kunt zien op de bovenstaande schermafbeelding, haalt INNER JOIN records op die in beide tabellen voorkomen. Het vult alle records uit de juiste tabel. Daarom kunt u dubbele records zien.

Laten we nu het DISTINCT-sleutelwoord toevoegen aan de INNER JOIN-query en kijken wat dit doet:

SELECTEER DISTINCT A.NAME, A.BUSINESSENTITYID, A.NATIONALIDNUMBER, A.BIRTHDATE, A.GENDER VAN WERKNEMER A INNER WORD LID VAN TRAINEE B OP A.NAME =B.NAME

De uitvoer zou er als volgt uit moeten zien:

Zoals je kunt zien op de bovenstaande schermafbeelding, zijn dubbele records geëlimineerd.

INTERSECT en INNER JOIN behandelen NULL-waarden anders. Voor INNER JOIN zijn twee NULL-waarden verschillend, dus er is een kans dat ze worden overgeslagen terwijl twee tabellen worden samengevoegd.

Aan de andere kant behandelt INTERSECT twee NULL-waarden als hetzelfde, dus records met NULL-waarden worden niet geëlimineerd. Laten we een voorbeeld bekijken om het beter te begrijpen.

Laten we eerst enkele NULL-waarden toevoegen aan de Trainee en Medewerker tabellen door de volgende query uit te voeren:

INSERT [DBO].[TRAINEE] ([NAME], [BUSINESSENTITYID], [NATIONALIDNUMBER], [BIRTHDATE], [GENDER]) WAARDEN (NULL, 3, N'509647174', CAST(N'1974-11) -12' ALS DATUM), N'M')GOINSERT [DBO].[Medewerker] ([NAAM], [BUSINESSENTITYID], [NATIONALIDNUMBER],[LOGINID], [GEBOORTEDATUM],[MARITALSTATUS], [GENDER]) WAARDEN (NULL, 3, N'509647174','ADVENTURE-WORKS\TERRI0', CAST(N'1974-11-12' ALS DATUM), N'M',N'M')GO

Laten we nu proberen records op te halen die de twee tabellen gemeen hebben met INTERSECT en INNER JOIN. U moet de volgende query uitvoeren:

/*QUERY WITH INTERSECT*/ SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, GEBOORTEDATUM, GESLACHT VAN WERKNEMER INTERSECT SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, GEBOORTE, GESLACHT VAN TRAINEE /*QUERY MET INNERLIJKE NAAM*, EEN. BUSINESSENTITYID, A.NATIONALIDNUMBER, A.GEBOORTEDATUM, A.GENDER VAN WERKNEMER A INNER WORD LID VAN TRAINEE B OP A.NAAM =B.NAAM

Dit is de output die we als resultaat zouden moeten krijgen:

Zoals u hierboven kunt zien, bevat de resultaatset die is gegenereerd door INTERSECT NULL-waarden, terwijl INNER JOIN de records met NULL-waarden heeft overgeslagen.

De BEHALVE Operator

Laten we eens kijken naar een use-case om de EXCEPT-operator in actie te demonstreren. Ik wil bijvoorbeeld de gegevens van vrouwelijke werknemers invullen uit de tabel Medewerker. De volgende vraag helpt ons daarbij:

SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, BIRTHDATE, GENDER VAN WERKNEMER WHERE GENDER ='F' BEHALVE SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, BIRTHDATE, GENDER VAN WERKNEMER WHERE GENDER ='M' 

Dit is de output die we krijgen:

Zoals je hierboven kunt zien, bevatte de zoekopdracht alleen de gegevens van de vrouwelijke werknemers.

U kunt de resultatenset ook vullen met een subquery:

SELECTEER NAAM, BUSINESSENTITYID, NATIONALIDNUMBER, GEBOORTEDATUM, GESLACHT VAN WERKNEMER ALS M WHERE GENDER ='F' EN GENDER NOT IN (SELECTEER HET GESLACHT VAN WERKNEMER AS F WHERE GENDER ='M')

Beperkingen van INTERSECT en BEHALVE

  1. We kunnen EXCEPT en INTERSECT niet gebruiken in gedistribueerde gepartitioneerde weergavedefinities met COMPUTE- en COMPUTE BY-clausules.
  2. EXCEPT en INTERSECT kunnen worden gebruikt in alleen vooruitspoelen en statische cursors.
  3. EXCEPT en INTERSECT kunnen worden gebruikt in gedistribueerde query's, maar kunnen alleen worden uitgevoerd op de lokale server. U kunt ze niet op een externe server uitvoeren.

Samenvatting

In dit artikel heb ik het volgende behandeld:

  1. De EXCEPT- en INTERSECT-operators.
  2. Het verschil tussen INTERSECT en INNER JOIN.
  3. Een gedetailleerde uitleg van de INTERSECT- en EXCEPT-operatoren met een voorbeeld.

  1. Het uitvoeren van meerdere instructies met Postgresql via SQLAlchemy houdt geen wijzigingen in stand

  2. SQL Server 2016 op Linux

  3. psycopg2:voeg meerdere rijen in met één query

  4. Benieuwd naar de nieuwste Microsoft Access-functies?