टेबल वैल्यू फंक्शन वाली टेबल से कैसे जुड़ें?


53

मेरे पास एक उपयोगकर्ता परिभाषित फ़ंक्शन है:

create function ut_FooFunc(@fooID bigint, @anotherParam tinyint)
returns @tbl Table (Field1 int, Field2 varchar(100))
as
begin
  -- blah blah
end

अब मैं इसे अन्य तालिका में शामिल करना चाहता हूं, जैसे:

select f.ID, f.Desc, u.Field1, u.Field2
from Foo f 
join ut_FooFunc(f.ID, 1) u -- doesn't work
where f.SomeCriterion = 1

दूसरे शब्दों में, सभी Fooरिकॉर्ड्स के लिए जहां SomeCriterion1 है, मैं Foo IDऔर Descके मूल्यों के साथ, Field1और Field2जो ut_FooFuncइनपुट के लिए लौटाए गए हैं , को देखना चाहता हूं Foo.ID

ऐसा करने के लिए वाक्यविन्यास क्या है?

जवाबों:


84

आपको CROSS APPLYशामिल होने की आवश्यकता नहीं है।

जोड़ों में शामिल तालिका अभिव्यक्तियों की परिभाषा स्थिर होनी चाहिए। यानी उन्हें इस तरह सहसंबद्ध नहीं किया जा सकता है कि तालिका की अभिव्यक्ति का मतलब किसी अन्य तालिका में एक पंक्ति के मूल्य पर कुछ अलग निर्भर है।

select f.ID, f.Desc, u.Field1, u.Field2
from Foo f 
Cross apply ut_FooFunc(f.ID, 1) u
where f.SomeCriterion = ...

0

मुझे पता है कि धागा पुराना है, मुझसे एक ही सवाल पूछा गया था, मैंने एक परीक्षण किया, परिणाम निम्नानुसार है ...

FacCurrencyRate में रिकॉर्ड = 14264 जबकि TestFunction 105 स्वतंत्र रूप से निष्पादित किया जाता है।

    SELECT F.*, x.CurrencyKey, x.CurrencyName
    FROM ( 
           SELECT CurrencyKey, CurrencyName FROM dbo.TestFunction()
        ) x
    INNER JOIN [dbo].[FactCurrencyRate] F ON x.CurrencyKey = f.CurrencyKey;

निष्पादन समय है ...

    (14264 rows affected)
    Table 'FactCurrencyRate'. Scan count 1, logical reads 75, physical reads 1, read-ahead reads 73, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DimCurrency'. Scan count 1, logical reads 2, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 31 ms,  elapsed time = 749 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

यदि मैं सुझाए गए उत्तर का उपयोग इस प्रकार करता हूं ...

select F.*, x.CurrencyKey, x.CurrencyName from [dbo].[FactCurrencyRate] F
cross apply dbo.TestFunction() x

निष्पादन समय और परिणाम गणना है ...

(1497720 rows affected)
Table 'FactCurrencyRate'. Scan count 1, logical reads 75, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 38110, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DimCurrency'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2106 ms,  elapsed time = 43242 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

जो मैं यहां देख रहा हूं वह यह है कि आंतरिक क्वेरी परिणाम का अधिक सही सेट लाती है और निष्पादन समय बहुत अधिक कुशल है। मुझे पूरा करने के लिए बेहतर दृष्टिकोण के साथ सही करें!


1
प्रत्येक बाहरी पंक्ति (पंक्ति द्वारा पंक्ति) पर क्रॉस लागू किया जाता है, यही कारण है कि यह इतना धीमा है, खासकर बड़े डेटासेट पर। इसे उल्टा करके (क्योंकि आप केवल परिणाम चाहते हैं जिनका टीवीएफ में एक मैच है तो आप एक्सट्यूशन समय (कोई कॉल जो कुछ भी नहीं करते हैं) को बहुत कम कर देते हैं और साथ ही कितनी पंक्तियाँ आपको वापस मिल जाती हैं। लेकिन आपके दो कथन दूसरे के बराबर नहीं हैं। पहले की तुलना में कहीं अधिक पंक्तियाँ लौटाता है। जहाँ तक शुद्धता जाती है, यह आपकी व्यावसायिक आवश्यकताओं पर निर्भर करता है।
जोनाथन फाइट

हाँ मैं सहमत हूँ। हालाँकि, मैंने प्रारंभिक प्रश्न के प्रकाश में कोड लिखा था, जहाँ मैंने माना कि तालिकाओं के बीच कई संबंधों में एक है। और, दूसरी बात, मुझे एक साक्षात्कार में एक प्रश्न पूछा गया था। धन्यवाद
user3104116
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.