परिचय
टी-एसक्यूएल हमें एक से अधिक टेबल से रिकॉर्ड को संयोजित करने और उन्हें एक परिणाम सेट के रूप में वापस करने की अनुमति देता है। यह SQL सर्वर में शामिल होने की अवधारणा के माध्यम से प्राप्त किया जाता है।
यह अवसर अक्सर आवश्यक होता है क्योंकि संबंधपरक डेटाबेस में डेटा आमतौर पर सामान्यीकृत होता है। उदाहरण के लिए, हमारे पास कर्मचारी डेटा दो या अधिक तालिकाओं में फैला हुआ है। पहली तालिका मूल ग्राहक डेटा होगी और इसे कर्मचारी कहा जाएगा। दूसरी तालिका होगी विभाग ।
डेटा संगतता के लिए ग्राहक और विभाग के बीच सही संबंध की आवश्यकता होती है। कर्मचारियों और उनके विभागों के एक समूह के लिए पूरा डेटा लौटाने के लिए दोनों तालिकाओं में शामिल होना आवश्यक है।
SQL जॉइन ऑपरेशंस में दो से अधिक टेबल भी शामिल हो सकते हैं।
तालिकाओं के बीच ऐसे विदेशी कुंजी संबंधों के अस्तित्व का एक अन्य मामला सारांश . के लिए है और विवरण टेबल.
AdventureWorks या WideWorldImporters नमूना डेटाबेस के साथ काम करने वाले लोग Sales.Orders से परिचित हैं और Sales.OrderDetails टेबल। इस मामले में, बाद वाले में Sales.Orders . में दर्ज प्रत्येक ऑर्डर का विवरण होता है टेबल। आदेश के आधार पर दो तालिकाओं का संबंध होता है। इस प्रकार, हम जॉइन का उपयोग करके एकल परिणाम सेट के रूप में दोनों तालिकाओं से डेटा पुनर्प्राप्त कर सकते हैं।
SQL सर्वर जॉइन के प्रकार
T-SQL निम्न प्रकार के जुड़ने की अनुमति देता है:
- आंतरिक जुड़ाव क्वेरी में शामिल सभी तालिकाओं के लिए सामान्य सभी रिकॉर्ड लौटाता है।
- बाएं (बाहरी) शामिल हों बाएं . से सभी रिकॉर्ड लौटाता है तालिका और सभी रिकॉर्ड दाएं . से तालिका जो बाईं तालिका में भी होती है। शर्तें बाएं और दाएं जॉइन क्लॉज के सापेक्ष तालिका की स्थिति देखें।
- दाएं (बाहरी) शामिल हों दाएं . से सभी रिकॉर्ड लौटाता है तालिका और सभी रिकॉर्ड बाएं . से तालिका जो बाईं तालिका में भी होती है। शर्तें पिछले मामले के समान हैं।
- पूर्ण बाहरी जुड़ाव दोनों तालिकाओं के सभी रिकॉर्ड, साथ ही दोनों तालिकाओं के अन्य सभी रिकॉर्ड लौटाता है। जिन स्तंभों की दूसरी तालिका में संगत पंक्तियाँ नहीं हैं, वे NULL लौटाते हैं
- क्रॉस जॉइन करें , इसे कार्टेशियन जॉइन . भी कहा जाता है , दोनों तालिकाओं से डेटा का कार्टेशियन उत्पाद लौटाता है। इसलिए, तालिका A में प्रत्येक पंक्ति के लिए निर्धारित अंतिम परिणाम में तालिका B की सभी पंक्तियों का मानचित्रण होगा, और इसके विपरीत।
यह लेख SQL INNER JOINs पर केंद्रित होगा।
नमूना तालिकाएं
आंतरिक जुड़ाव की अवधारणा को प्रदर्शित करने के लिए, हम इत्ज़िक बेन-गण द्वारा निर्मित TSQLV4 डेटाबेस से तीन संबंधित तालिकाओं का उपयोग करते हैं।
निम्नलिखित सूचियाँ इन तालिकाओं की संरचना दिखाती हैं।
-- 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
बिक्री में कस्टिड कॉलम के बीच विदेशी कुंजी संबंध नोट करें। ऑर्डर और Sales.Customers में कस्टिड कॉलम ।
जॉइन करने के लिए, हमें जॉइन आधार के रूप में इस तरह के एक सामान्य कॉलम को निर्दिष्ट करना होगा।
जॉइन प्रश्नों को निष्पादित करने के लिए इसे विदेशी कुंजी संबंध की सख्ती से आवश्यकता नहीं होती है, लेकिन परिणाम सेट निर्धारित करने वाले कॉलम तुलनीय होने चाहिए।
विदेशी कुंजी जॉइन प्रश्नों को बेहतर बनाने में भी मदद कर सकती है, खासकर यदि विदेशी कुंजी कॉलम अनुक्रमित है।
-- 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
नमूना प्रश्न SQL इनर जॉइन के साथ
आइए SQL INNER JOIN का उपयोग करके कुछ नमूना क्वेरी निष्पादित करें।
लिस्टिंग 4 में, हम एक क्वेरी निष्पादित करते हैं जो Sales.Customers तालिका और Sales.Orders तालिका के लिए सभी पंक्तियों को साझा करती है। हम शामिल होने की शर्त के रूप में कस्टिड कॉलम का उपयोग करते हैं।
ध्यान दें कि ON क्लॉज WHERE क्लॉज की तरह ही एक फिल्टर है। हमने तालिकाओं में अंतर करने के लिए उपनामों का भी उपयोग किया है।
-- Listing 4: Customer Orders
use TSQLV4
go
select * from Sales.Customers sc
inner join Sales.Orders so
on sc.custid=so.custid;
लिस्टिंग 5 में, हम क्वेरी को विशिष्ट कॉलम तक सीमित कर देते हैं Sales.Customers तालिका और बिक्री.आदेश टेबल। हम कस्टिड . का उपयोग करते हैं कॉलम में शामिल होने की शर्त के रूप में।
ध्यान दें कि ON क्लॉज WHERE क्लॉज की तरह ही एक फिल्टर है। हमने तालिकाओं में अंतर करने के लिए उपनामों का भी उपयोग किया है।
-- 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;
लिस्टिंग 6 में, हम एक WHERE क्लॉज पेश करके विचार का विस्तार करते हैं जो एकल ग्राहक के लिए डेटा फ़िल्टर करता है। हमने कॉलम सूची में उपनाम भी जोड़े हैं।
हालांकि इस उदाहरण में यह आवश्यक नहीं है, ऐसे मामले हैं जहां आपको दोनों तालिकाओं से समान नाम वाले कॉलम प्रोजेक्ट करने की आवश्यकता होती है। फिर, कॉलम को दो-भाग के नामों के रूप में एक व्यंजक की आवश्यकता होगी, तालिका उपनामों या नामों का उपयोग करते हुए।
-- 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';
लिस्टिंग 7 में, हम custid कॉलम का परिचय देते हैं। हम उपनाम का उपयोग करके स्तंभों में अंतर कर सकते हैं, लेकिन हम दो कस्टिड में अंतर नहीं कर सकते हैं आउटपुट में कॉलम (चित्र 4 देखें)। हम उपनामों का उपयोग करके इसे ठीक कर सकते हैं:
-- 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';
लिस्टिंग 9 में, हम मिक्स में Sales.OrderDetails टेबल जोड़ते हैं। दो से अधिक तालिकाओं में शामिल होने पर, पहले दो तालिकाओं से सेट किया गया परिणाम जॉइन बाएं बन जाता है अगली तालिका के लिए तालिका। हालांकि, जॉइन क्वेरी में तालिकाओं का क्रम अंतिम आउटपुट को प्रभावित नहीं करता है।
ध्यान दें कि हम 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';
लिस्टिंग 10 में उत्पादन का परिचय दिया गया है। उत्पाद तालिका हमें ऑर्डर से जुड़े उत्पाद विवरण दिखाती है।
-- 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';
गैर-समतुल्य जॉइन
चूंकि ON क्लॉज एक फिल्टर है, हम "=" ऑपरेटर के अलावा अन्य ऑपरेटरों का उपयोग कर सकते हैं। JOIN आमतौर पर ON क्लॉज में <,>, !=, =<और => जैसी असमानताओं के उपयोग का समर्थन करते हैं। लिस्टिंग 11 इसे प्रदर्शित करता है।
इन प्रश्नों को चलाने से विभिन्न परिणाम सेट वापस आ जाएंगे।
-- 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;
निष्कर्ष
इस लेख ने SQL INNER JOINs पर चर्चा की और इसके उपयोग के उदाहरण प्रस्तुत किए। इसने एक ही क्वेरी में दो, तीन और चार तालिकाओं के साथ परिदृश्यों को कवर किया।
संबंधित तालिकाओं का उपयोग करते हुए, हमने यह भी दिखाया है कि हम अपनी आवश्यकताओं के अनुसार आउटपुट प्रदर्शित करने के लिए क्वेरी संरचना को कैसे बदल सकते हैं। हमने गैर-समतुल्य जॉइन के संक्षिप्त उदाहरण भी जोड़े हैं।