आपको CROSS APPLY
की आवश्यकता है यहां, यह बाहरी संदर्भों को संदर्भित कर सकता है, कोई कष्टप्रद उपश्रेणी या सीटीई की आवश्यकता नहीं है:
select col1, col2
from table1 as outer_table
-- can also have multi-row values
cross apply (values (complex_expression_1) ) as v1 (col1)
cross apply (values (expression_referring_to_col1) ) as v2 (col2)
-- alternate syntax, select without from returns a single row
cross apply (select complex_expression_1 as col1 ) AS v1
cross apply (select expression_referring_to_col1 as col2 ) as v2
-- you can also do anything you like in there, can be one or multiple rows
cross apply (
select complex_expression_1 as col1
from othercomplexjoin as o
where o.join_column = outer_table.join_column
) AS v1
कुछ और तरकीबें जो आप APPLY
के साथ कर सकते हैं :
<मजबूत>1. चाइल्ड टेबल के प्रति समूह शीर्ष 1:
"प्रति समूह शीर्ष 1" का एक उत्कृष्ट समाधान row_number()
. का उपयोग करना है . इसका परिणाम अक्सर बड़े स्कैन में हो सकता है, खासकर जब अलग-अलग बाहरी मानों की संख्या चाइल्ड टेबल के सापेक्ष कम होती है।
select
o.id,
lastPayment.Date
from order_header as o
join
( select *, row_number() over (partition by order_id order by date desc) as rn
from payments
) as lastPayment on ...
where lastPayment.rn = 1
इसके बजाय हम यह कर सकते हैं:
select
o.id,
lastPayment.Date
from order_header as o
cross apply
( select top (1) *
from payments as p
where p.order_id = o.id
order by date desc
) as lastPayment
नोट:OUTER APPLY
वैचारिक रूप से एक लेफ्ट जॉइन की जगह लेता है, यानी बिना पंक्तियों के नल देता है।
<मजबूत>2. अनपिवट करना
select
o.id,
customer.*
from order_header as o
cross apply ( values -- This returns two rows for every order_header
( 'DeliveryCustomer', o.deliveryCustomer ),
( 'billingCustomer', o.billingCustomer )
) as customer (type, name)
<मजबूत>3. एक पंक्ति को एक चर संख्या में बार-बार विस्फोट करना:
मान लें कि हम एक राशि लेना चाहते हैं, और इसे अलग-अलग पंक्तियों में विभाजित करना चाहते हैं। अगर amount <= 50
फिर amount
. की एक पंक्ति , अगर > 50
फिर दो पंक्तियाँ, 50 में से एक और बाकी में से एक:
select t.id, v.amount
from table as t
cross apply (
select case when amount > 50 then 50 else amount end as amount
union all
select amount - 50 -- note this row will not appear if amount < 50
where amount > 50
) v