Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Operator SET T-SQL Bagian 2:INTERSECT dan KECUALI

Pada artikel saya sebelumnya, saya menjelaskan dasar-dasar operator himpunan, jenisnya, dan prasyarat penggunaannya. Saya juga berbicara tentang operator UNION dan UNION ALL, penggunaan dan perbedaannya.

Dalam artikel ini, kita akan mempelajari hal berikut:

  1. Operator KECUALI dan INTERSECT.
  2. Perbedaan antara INTERSECT dan INNER JOIN.
  3. Penjelasan rinci tentang INTERSECT dan KECUALI dengan sebuah contoh.

Operator KECUALI dan INTERSECT diperkenalkan di SQL Server 2005. Keduanya adalah operator set yang digunakan untuk menggabungkan set hasil yang dihasilkan oleh dua kueri dan mengambil output yang diinginkan.

Apa itu operator INTERSECT

INTERSECT digunakan untuk mendapatkan catatan umum untuk semua kumpulan data yang diambil dari beberapa kueri atau tabel. Berikut visualisasinya:

Sintaks dari operator INTERSECT adalah sebagai berikut:

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

Apa itu operator KECUALI

KECUALI digunakan untuk mengambil catatan yang ditemukan dalam satu kueri tetapi tidak dalam kueri lain. Dengan kata lain, ini mengembalikan catatan yang unik untuk satu set hasil. Ini penampakan visualisasinya:

Sintaks dari operator KECUALI adalah sebagai berikut:

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

Mari buat setup demo untuk mendemonstrasikan bagaimana operator ini dapat digunakan.

Penyiapan Demo

Untuk mendemonstrasikan INTERSECT dan EXCEPT, saya membuat dua tabel bernama Karyawan dan Pelatih .

Jalankan kueri berikut untuk membuat tabel ini:

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]

Sekarang, mari kita masukkan beberapa data dummy ke dalam Karyawan tabel dengan mengeksekusi query berikut:

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')

Selanjutnya, kita akan melakukan hal yang sama untuk Trainee tabel:

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

Sekarang, mari kita gunakan INTERSECT untuk mengambil daftar karyawan yang umum untuk kedua tabel. Untuk melakukannya, jalankan kueri berikut:

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

Output dari kueri ini harus sebagai berikut:

Seperti yang Anda lihat pada tangkapan layar di atas, kueri hanya mengembalikan catatan yang umum untuk kedua tabel.

INNER JOIN vs. INTERSECT

Dalam kebanyakan kasus, INTERSECT dan INNER JOIN mengembalikan output yang sama, tetapi ada beberapa pengecualian. Contoh sederhana akan membantu kita memahami hal ini.

Mari tambahkan beberapa record duplikat ke tabel Trainee. Jalankan kueri berikut:

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

Sekarang, kita akan mencoba menghasilkan output yang diinginkan menggunakan INTERSECT.

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

Ini adalah output yang kita dapatkan:

Sekarang, mari kita coba menggunakan 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

Output yang kita dapatkan dalam hal ini adalah sebagai berikut:

Sekarang, seperti yang Anda lihat pada tangkapan layar di atas, INNER JOIN mengambil catatan yang umum untuk kedua tabel. Ini mengisi semua catatan dari tabel kanan. Oleh karena itu, Anda dapat melihat catatan duplikat.

Sekarang, mari tambahkan kata kunci DISTINCT ke kueri INNER JOIN dan lihat apa fungsinya:

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

Outputnya akan terlihat seperti ini:

Seperti yang Anda lihat pada tangkapan layar di atas, catatan duplikat telah dihilangkan.

INTERSECT dan INNER JOIN memperlakukan nilai NULL secara berbeda. Untuk INNER JOIN, dua nilai NULL berbeda, jadi ada kemungkinan nilai tersebut akan dilewati saat menggabungkan dua tabel.

Di sisi lain, INTERSECT memperlakukan dua nilai NULL sebagai sama, sehingga catatan yang memiliki nilai NULL tidak akan dihilangkan. Untuk lebih memahaminya, mari kita lihat sebuah contoh.

Pertama, mari tambahkan beberapa nilai NULL ke Trainee dan Karyawan tabel dengan mengeksekusi query berikut:

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

Sekarang mari kita coba mengambil record yang umum untuk dua tabel menggunakan INTERSECT dan INNER JOIN. Anda perlu menjalankan kueri berikut:

/*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

Ini adalah output yang harus kita dapatkan sebagai hasilnya:

Seperti yang Anda lihat di atas, kumpulan hasil yang dihasilkan oleh INTERSECT berisi nilai NULL, sementara INNER JOIN melewatkan catatan yang memiliki nilai NULL.

KECUALI Operator

Untuk mendemonstrasikan operator KECUALI beraksi, mari kita lihat kasus penggunaan. Misalnya, saya ingin mengisi detail karyawan wanita dari tabel Karyawan. Kueri berikut akan membantu kami melakukan hal itu:

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

Ini adalah output yang kita dapatkan:

Seperti yang Anda lihat di atas, kueri hanya mengisi detail karyawan wanita.

Anda juga dapat mengisi kumpulan hasil menggunakan sub-kueri:

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')

Batasan INTERSECT dan KECUALI

  1. Kami tidak dapat menggunakan KECUALI dan INTERSECT dalam definisi tampilan terpartisi terdistribusi dengan klausa COMPUTE dan COMPUTE BY.
  2. KECUALI dan INTERSECT dapat digunakan di hanya maju cepat dan kursor statis.
  3. KECUALI dan INTERSECT dapat digunakan dalam kueri terdistribusi, tetapi hanya dapat dijalankan di server lokal. Anda tidak dapat menjalankannya di server jauh.

Ringkasan

Dalam artikel ini, saya telah membahas:

  1. Operator KECUALI dan INTERSECT.
  2. Perbedaan antara INTERSECT dan INNER JOIN.
  3. Penjelasan rinci tentang operator INTERSECT dan KECUALI dengan sebuah contoh.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Utilitas verifikasi cluster menghasilkan sejumlah besar file xml pada sistem file "/ u01".

  2. Pertanyaan SQL

  3. Desain Basis Data 101

  4. Menghubungkan Aplikasi 64-bit ke Clarion TopSpeed

  5. Memulihkan Contoh DW Database AdventureWorksDW2019