INNER JOIN
और CROSS APPLY
(LEFT JOIN
. के साथ भी ऐसा ही और OUTER APPLY
) बहुत निकट से संबंधित हैं। आपके उदाहरण में मुझे लगता है कि इंजन को वही निष्पादन योजना मिलेगी।
- एक
JOIN
एक शर्त पर दो सेटों के बीच की कड़ी है - एक
APPLY
एक पंक्ति-वार है उप-कॉल
लेकिन - जैसा कि ऊपर बताया गया है - ऑप्टिमाइज़र बहुत स्मार्ट है और - कम से कम ऐसे आसान मामलों में - समझें, कि यह उसी के लिए नीचे आता है।
- द
JOIN
उप-सेट को एकत्रित करने और उसे लिंक करने का प्रयास करेगा निर्दिष्ट शर्त पर APPLY
संबंधित परिणाम को वर्तमान पंक्ति के मानों के साथ कॉल करने का प्रयास करेंगे बार-बार।
टेबल-वैल्यू-फ़ंक्शंस को कॉल करने में अंतर है (इनलाइन होना चाहिए -सिंटैक्स!), XML-विधि के साथ .nodes()
और अधिक जटिल परिदृश्यों के साथ।
एक उदाहरण कि कैसे कोई APPLY
का उपयोग कर सकता है चर का अनुकरण करने के लिए
...एक पंक्ति-वार . के परिणाम का उपयोग करने के लिए गणना जैसे आप एक चर का उपयोग करेंगे:
DECLARE @dummy TABLE(ID INT IDENTITY, SomeString VARCHAR(100));
INSERT INTO @dummy VALUES('Want to split/this at the two/slashes.'),('And/this/also');
SELECT d.ID
,d.SomeString
,pos1
,pos2
,LEFT(d.SomeString,pos1-1)
,SUBSTRING(d.SomeString,pos1+1,pos2-pos1-1)
,SUBSTRING(d.SomeString,pos2+1,1000)
FROM @dummy AS d
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString) AS pos1) AS x
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString,x.pos1+1) AS pos2) AS y
यह निम्नलिखित जैसा ही है, लेकिन पढ़ने में बहुत आसान है (और टाइप करें):
SELECT d.ID
,d.SomeString
,LEFT(d.SomeString,CHARINDEX('/',d.SomeString)-1)
,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString)+1,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))-(CHARINDEX('/',d.SomeString)+1))
,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))+1,1000)
FROM @dummy AS d
XML-विधि के साथ एक उदाहरण .nodes()
DECLARE @dummy TABLE(SomeXML XML)
INSERT INTO @dummy VALUES
(N'<root>
<a>a1</a>
<a>a2</a>
<a>a3</a>
<b>Here is b!</b>
</root>');
SELECT All_a_nodes.value(N'.',N'nvarchar(max)')
FROM @dummy
CROSS APPLY SomeXML.nodes(N'/root/a') AS A(All_a_nodes);
परिणाम
a1
a2
a3
और इनलाइन फ़ंक्शन कॉल के लिए एक उदाहरण
CREATE FUNCTION dbo.TestProduceRows(@i INT)
RETURNS TABLE
AS
RETURN
SELECT TOP(@i) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nr FROM master..spt_values
GO
CREATE TABLE dbo.TestData(ID INT IDENTITY, SomeString VARCHAR(100),Number INT);
INSERT INTO dbo.TestData VALUES
('Show me once',1)
,('Show me twice',2)
,('Me five times!',5);
SELECT *
FROM TestData
CROSS APPLY dbo.TestProduceRows(Number) AS x;
GO
DROP TABLE dbo.TestData;
DROP FUNCTION dbo.TestProduceRows;
परिणाम
1 Show me once 1 1
2 Show me twice 2 1
2 Show me twice 2 2
3 Me five times! 5 1
3 Me five times! 5 2
3 Me five times! 5 3
3 Me five times! 5 4
3 Me five times! 5 5