Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL Server Inner Join Basics with Contoh

Pengantar

T-SQL memungkinkan kita untuk menggabungkan catatan dari lebih dari satu tabel dan mengembalikannya sebagai satu set hasil. Ini dicapai melalui konsep join di SQL Server.

Kesempatan ini sering diperlukan karena data dalam database relasional biasanya dinormalisasi. Misalnya, kami memiliki data karyawan yang tersebar di dua atau lebih tabel. Tabel pertama akan menjadi data pelanggan dasar dan disebut karyawan. Tabel kedua adalah departemen .

Konsistensi data membutuhkan hubungan yang benar antara pelanggan dan departemen. Mengembalikan data lengkap untuk satu set karyawan dan departemen mereka harus menggabungkan kedua tabel.

Operasi gabungan SQL juga dapat mencakup lebih dari dua tabel.

Kasus lain dari keberadaan hubungan Kunci asing di antara tabel adalah untuk ringkasan dan detail tabel.

Orang yang bekerja dengan database sampel AdventureWorks atau WideWorldImporters sudah familiar dengan Sales.Orders dan tabel Sales.OrderDetails. Dalam hal ini, yang terakhir berisi rincian setiap pesanan yang dicatat di Sales.Orders meja. Dua tabel memiliki hubungan berdasarkan urutan. Dengan demikian, kita dapat mengambil data dari kedua tabel sebagai satu set hasil menggunakan GABUNG.

Jenis SQL Server GABUNG

T-SQL memungkinkan jenis gabungan berikut:

  1. Gabungan Batin mengembalikan semua catatan umum untuk semua tabel yang terlibat dalam kueri.
  2. Kiri (Luar) Gabung mengembalikan semua catatan dari kiri tabel dan semua catatan dari kanan tabel yang juga terjadi di tabel kiri. Istilah kiri dan benar merujuk ke posisi tabel relatif terhadap klausa JOIN.
  3. Kanan (Luar) Gabung mengembalikan semua catatan dari kanan tabel dan semua catatan dari kiri tabel yang juga terjadi di tabel kiri. Istilahnya mirip dengan kasus sebelumnya.
  4. Gabung Luar Penuh mengembalikan semua catatan umum untuk kedua tabel, ditambah semua catatan lain dari kedua tabel. Kolom yang tidak memiliki baris yang sesuai di tabel lain mengembalikan NULL
  5. Gabung Salib , juga disebut Gabung Kartesius , mengembalikan produk kartesius data dari kedua tabel. Oleh karena itu, hasil akhir yang ditetapkan untuk setiap baris pada tabel A akan berisi pemetaan semua baris pada tabel B, dan sebaliknya.

Artikel ini akan fokus pada SQL INNER JOIN.

Tabel Contoh

Untuk mendemonstrasikan konsep inner join, kami menggunakan tiga tabel terkait dari database TSQLV4 yang dibuat oleh Itzik Ben-Gan.

Daftar berikut menunjukkan struktur tabel ini.

-- Listing 1: Structure of the Sales.Customers Table

CREATE TABLE [Sales].[Customers](
	[custid] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[companyname] [nvarchar](40) NOT NULL,
	[contactname] [nvarchar](30) NOT NULL,
	[contacttitle] [nvarchar](30) NOT NULL,
	[address] [nvarchar](60) NOT NULL,
	[city] [nvarchar](15) NOT NULL,
	[region] [nvarchar](15) NULL,
	[postalcode] [nvarchar](10) NULL,
	[country] [nvarchar](15) NOT NULL,
	[phone] [nvarchar](24) NOT NULL,
	[fax] [nvarchar](24) NULL,
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED 
(
	[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

Perhatikan hubungan kunci asing antara kolom custid di Sales.Orders dan kolom custid di Sales.Customers .

Untuk melakukan JOIN, kita harus menentukan kolom umum seperti basis JOIN.

Itu tidak sepenuhnya memerlukan hubungan kunci asing untuk menjalankan kueri GABUNG, tetapi kolom yang menentukan kumpulan hasil harus sebanding.

Kunci Asing juga dapat membantu meningkatkan kueri GABUNG, terutama jika kolom kunci asing diindeks.

-- Listing 2: Structure of the Sales.Orders Table

CREATE TABLE [Sales].[Orders](
	[orderid] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[custid] [int] NULL,
	[empid] [int] NOT NULL,
	[orderdate] [date] NOT NULL,
	[requireddate] [date] NOT NULL,
	[shippeddate] [date] NULL,
	[shipperid] [int] NOT NULL,
	[freight] [money] NOT NULL,
	[shipname] [nvarchar](40) NOT NULL,
	[shipaddress] [nvarchar](60) NOT NULL,
	[shipcity] [nvarchar](15) NOT NULL,
	[shipregion] [nvarchar](15) NULL,
	[shippostalcode] [nvarchar](10) NULL,
	[shipcountry] [nvarchar](15) NOT NULL,
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
	[orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [Sales].[Orders] ADD  CONSTRAINT [DFT_Orders_freight]  DEFAULT ((0)) FOR [freight]
GO
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Customers] FOREIGN KEY([custid])
REFERENCES [Sales].[Customers] ([custid])
GO
ALTER TABLE [Sales].[Orders] CHECK CONSTRAINT [FK_Orders_Customers]
GO
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Employees] FOREIGN KEY([empid])
REFERENCES [HR].[Employees] ([empid])
GO
ALTER TABLE [Sales].[Orders] CHECK CONSTRAINT [FK_Orders_Employees]
GO
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Shippers] FOREIGN KEY([shipperid])
REFERENCES [Sales].[Shippers] ([shipperid])
GO
ALTER TABLE [Sales].[Orders] CHECK CONSTRAINT [FK_Orders_Shippers]
GO
-- Listing 3: Structure of the Sales.OrderDetails Table

CREATE TABLE [Sales].[OrderDetails](
	[orderid] [int] NOT NULL,
	[productid] [int] NOT NULL,
	[unitprice] [money] NOT NULL,
	[qty] [smallint] NOT NULL,
	[discount] [numeric](4, 3) NOT NULL,
 CONSTRAINT [PK_OrderDetails] PRIMARY KEY CLUSTERED 
(
	[orderid] ASC,
	[productid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [Sales].[OrderDetails] ADD  CONSTRAINT [DFT_OrderDetails_unitprice]  DEFAULT ((0)) FOR [unitprice]
GO
ALTER TABLE [Sales].[OrderDetails] ADD  CONSTRAINT [DFT_OrderDetails_qty]  DEFAULT ((1)) FOR [qty]
GO
ALTER TABLE [Sales].[OrderDetails] ADD  CONSTRAINT [DFT_OrderDetails_discount]  DEFAULT ((0)) FOR [discount]
GO
ALTER TABLE [Sales].[OrderDetails]  WITH CHECK ADD  CONSTRAINT [FK_OrderDetails_Orders] FOREIGN KEY([orderid])
REFERENCES [Sales].[Orders] ([orderid])
GO
ALTER TABLE [Sales].[OrderDetails] CHECK CONSTRAINT [FK_OrderDetails_Orders]
GO
ALTER TABLE [Sales].[OrderDetails]  WITH CHECK ADD  CONSTRAINT [FK_OrderDetails_Products] FOREIGN KEY([productid])
REFERENCES [Production].[Products] ([productid])
GO
ALTER TABLE [Sales].[OrderDetails] CHECK CONSTRAINT [FK_OrderDetails_Products]
GO
ALTER TABLE [Sales].[OrderDetails]  WITH CHECK ADD  CONSTRAINT [CHK_discount] CHECK  (([discount]>=(0) AND [discount]<=(1)))
GO
ALTER TABLE [Sales].[OrderDetails] CHECK CONSTRAINT [CHK_discount]
GO
ALTER TABLE [Sales].[OrderDetails]  WITH CHECK ADD  CONSTRAINT [CHK_qty] CHECK  (([qty]>(0)))
GO
ALTER TABLE [Sales].[OrderDetails] CHECK CONSTRAINT [CHK_qty]
GO
ALTER TABLE [Sales].[OrderDetails]  WITH CHECK ADD  CONSTRAINT [CHK_unitprice] CHECK  (([unitprice]>=(0)))
GO
ALTER TABLE [Sales].[OrderDetails] CHECK CONSTRAINT [CHK_unitprice]
GO

Contoh Kueri dengan SQL INNER JOIN

Mari kita jalankan beberapa contoh kueri menggunakan SQL INNER JOIN.

Di Listing 4, kami menjalankan kueri yang mengambil SEMUA baris yang umum untuk tabel Sales.Customers dan tabel Sales.Orders. Kami menggunakan kolom custid sebagai syarat untuk bergabung.

Perhatikan bahwa klausa ON adalah filter yang sangat mirip dengan klausa WHERE. Kami juga menggunakan alias untuk membedakan tabel.

-- Listing 4: Customer Orders

use TSQLV4
go
select * from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid;

Di Listing 5, kami mempersempit kueri ke kolom tertentu ke Sales.Customers tabel dan Sales.Orders meja. Kami menggunakan custid kolom sebagai syarat untuk bergabung.

Perhatikan bahwa klausa ON adalah filter yang sangat mirip dengan klausa WHERE. Kami juga menggunakan alias untuk membedakan tabel.

-- Listing 5: Customer Orders with specific Rows
use TSQLV4
go
select
contactname
, contacttitle
, address
, orderid
, orderdate
, shipaddress
, shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid;

Di Listing 6, kami memperluas pemikiran dengan memperkenalkan klausa WHERE yang memfilter data untuk satu pelanggan. Kami juga telah menambahkan alias ke daftar kolom.

Meskipun tidak diperlukan dalam contoh ini, ada kasus di mana Anda perlu memproyeksikan kolom dengan nama yang sama dari kedua tabel. Kemudian, kolom akan membutuhkan ekspresi sebagai nama dua bagian, menggunakan alias atau nama tabel.

-- Listing 6: Customer Orders for a Single Customer
use TSQLV4
go
select 
sc.contactname
, sc.contacttitle
, sc.address
, so.orderid
, so.orderdate
, so.shipaddress
, so.shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid
where sc.contactname='Allen, Michael';

Dalam daftar 7, kami memperkenalkan kolom custid. Kita bisa membedakan kolom menggunakan alias, tapi kita tidak bisa membedakan keduanya custid kolom dalam output (Lihat Gambar 4). Kami dapat memperbaikinya dengan menggunakan alias:

-- Listing 7: Customer Orders for a Single Customer with Common Column
use TSQLV4
go
select 
sc.custid
, sc.contactname
, sc.contacttitle
, sc.address
, so.custid
, so.orderid
, so.orderdate
, so.shipaddress
, so.shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid
where sc.contactname='Allen, Michael';
-- Listing 8: Customer Orders for a Single Customer with Aliased Column
use TSQLV4
go
select 
sc.custid customer_custid
, sc.contactname
, sc.contacttitle
, sc.address
, so.custid order_custid
, so.orderid
, so.orderdate
, so.shipaddress
, so.shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid
where sc.contactname='Allen, Michael';

Di Listing 9, kami menambahkan tabel Sales.OrderDetails ke dalam campuran. Saat menggabungkan lebih dari dua tabel, hasil yang ditetapkan dari dua tabel pertama JOIN menjadi kiri meja untuk meja berikutnya. Namun, urutan tabel dalam kueri GABUNG tidak memengaruhi hasil akhirnya.

Perhatikan bahwa kami menggunakan wild card untuk mengambil SEMUA kolom dari tabel Sales.OrderDetails.

-- Listing 9: Inner Join with Three Tables

use TSQLV4
go
select 
sc.custid customer_custid
, sc.contactname
, sc.contacttitle
, sc.address
, so.custid order_custid
, so.orderid
, so.orderdate
, so.shipaddress
, so.shipcountry
, sod.*
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid
inner join Sales.OrderDetails sod
on so.orderid=sod.orderid
where sc.contactname='Allen, Michael';

Listing 10 memperkenalkan tabel Production.Product yang menunjukkan kepada kita detail produk yang terkait dengan pesanan.

-- Listing 10: Inner Join with Four Tables

use TSQLV4
go
select 
sc.custid customer_custid
, sc.contactname
, sc.contacttitle
, sc.address
, so.custid order_custid
, so.orderid
, so.orderdate
, so.shipaddress
, so.shipcountry
, sod.*
, pp.productname
, pp.unitprice
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid
inner join Sales.OrderDetails sod
on so.orderid=sod.orderid
inner join Production.Products pp
on sod.productid=pp.productid
where sc.contactname='Allen, Michael';

Non-Equi GABUNG

Karena klausa ON adalah filter, kita dapat menggunakan operator selain operator “=”. JOIN umumnya mendukung penggunaan ketidaksetaraan seperti <,>, !=, = dalam klausa ON. Daftar 11 menunjukkan hal ini.

Menjalankan kueri ini akan mengembalikan kumpulan hasil yang berbeda.

-- Listing 11: Non-Equi JOINs, "Equal to"
use TSQLV4
go
select
contactname
, contacttitle
, address
, orderid
, orderdate
, shipaddress
, shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid;
-- Listing 12: Non-Equi JOINs, "Not Equal to"
use TSQLV4
go
select
contactname
, contacttitle
, address
, orderid
, orderdate
, shipaddress
, shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid<>so.custid;
-- Listing 13: Non-Equi JOINs, "Less than OR Equal to"
use TSQLV4
go
select
contactname
, contacttitle
, address
, orderid
, orderdate
, shipaddress
, shipcountry
from Sales.Customers sc
inner join Sales.Orders so
on sc.custid<=so.custid;

Kesimpulan

Artikel ini membahas SQL INNER JOINs dan menyajikan contoh penggunaannya. Ini mencakup skenario dengan dua, tiga, dan empat tabel dalam kueri yang sama.

Menggunakan tabel terkait, kami juga telah mengilustrasikan bagaimana kami dapat memvariasikan struktur kueri untuk menampilkan output sesuai dengan kebutuhan kami. Kami juga telah menambahkan contoh singkat dari Non-Equi JOIN.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cara yang efisien untuk mengimplementasikan paging

  2. Apa cara berbeda untuk memasukkan data ke dalam Tabel SQL Server - Tutorial SQL Server / TSQL Bagian 100

  3. Cara Menginstal SQL Server di Mac

  4. Cara Menggunakan SQL Server HierarchyID Melalui Contoh Mudah

  5. SELECT max(x) mengembalikan nol; bagaimana saya bisa membuatnya kembali 0?