Wanneer moet ik CROSS APPLY over INNER JOIN gebruiken?

Wat is het belangrijkste doel van het gebruik van CROSS APPLY?

Ik heb gelezen (vaag via berichten op internet) dat CROSS APPLYefficiënter kan zijn bij het selecteren van grote datasets als je partitioneert. (Pagina komt in me op)

Ik weet ook dat CROSS APPLYgeen UDF als rechtertabel vereist.

In de meeste inner join-query’s (een-op-veel-relaties), zou ik ze kunnen herschrijven om CROSS APPLYte gebruiken, maar ze geven me altijd gelijkwaardige uitvoeringsplannen.

Kan iemand me een goed voorbeeld geven van wanneer CROSS APPLYeen verschil maakt in die gevallen waar inner joinook zal werken?


Bewerken:

Hier is een triviaal voorbeeld, waarbij de uitvoeringsplannen precies hetzelfde zijn. (Laat me er een zien waar ze verschillen en waar CROSS APPLYsneller/efficiënter is)

create table Company (
    companyId int identity(1,1)
,   companyName varchar(100)
,   zipcode varchar(10) 
,   constraint PK_Company primary key (companyId)
)
GO
create table Person (
    personId int identity(1,1)
,   personName varchar(100)
,   companyId int
,   constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
,   constraint PK_Person primary key (personId)
)
GO
insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'
insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3 
/* using CROSS APPLY */
select *
from Person p
cross apply (
    select *
    from Company c
    where p.companyid = c.companyId
) Czip
/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId

Antwoord 1, autoriteit 100%

Kan iemand me een goed voorbeeld geven van wanneer CROSS APPLY een verschil maakt in die gevallen waarin INNER JOIN ook werkt?

Zie het artikel in mijn blog voor gedetailleerde prestatievergelijking:

CROSS APPLYwerkt beter voor dingen die geen eenvoudige JOIN-voorwaarde hebben.

Deze selecteert 3laatste records van t2voor elk record van t1:

SELECT  t1.*, t2o.*
FROM    t1
CROSS APPLY
        (
        SELECT  TOP 3 *
        FROM    t2
        WHERE   t2.t1_id = t1.id
        ORDER BY
                t2.rank DESC
        ) t2o

Het kan niet gemakkelijk worden geformuleerd met een inner joinvoorwaarde.

Je zou waarschijnlijk zoiets kunnen doen met behulp van CTE‘s en window-functie:

WITH    t2o AS
        (
        SELECT  t2.*, ROW_NUMBER() OVER (PARTITION BY t1_id ORDER BY rank) AS rn
        FROM    t2
        )
SELECT  t1.*, t2o.*
FROM    t1
INNER JOIN
        t2o
ON      t2o.t1_id = t1.id
        AND t2o.rn <= 3

, maar dit is minder leesbaar en waarschijnlijk minder efficiënt.

Bijwerken:

Zojuist gecontroleerd.

Masteris een tabel van ongeveer 20,000,000records met een PRIMARY KEYop Id.

Deze zoekopdracht:

WITH    q AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY id) AS rn
        FROM    master
        ),
        t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
JOIN    q
ON      q.rn <= t.id

loopt bijna 30seconden, terwijl deze:

WITH    t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
CROSS APPLY
        (
        SELECT  TOP (t.id) m.*
        FROM    master m
        ORDER BY
                id
        ) q

is direct.


Antwoord 2, autoriteit 31%

Bedenk dat je twee tafels hebt.

HOOFDTAFEL

x------x--------------------x
| Id   |        Name        |
x------x--------------------x
|  1   |          A         |
|  2   |          B         |
|  3   |          C         |
x------x--------------------x

DETAILS TABEL

x------x--------------------x-------x
| Id   |      PERIOD        |   QTY |
x------x--------------------x-------x
|  1   |   2014-01-13       |   10  |
|  1   |   2014-01-11       |   15  |
|  1   |   2014-01-12       |   20  |
|  2   |   2014-01-06       |   30  |
|  2   |   2014-01-08       |   40  |
x------x--------------------x-------x

Er zijn veel situaties waarin we inner joinmoeten vervangen door CROSS APPLY.

1. Voeg twee tabellen samen op basis van TOP nresultaten

Overweeg of we Iden Namemoeten selecteren van Masteren de laatste twee datums voor elke Idvan Details table.

SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
INNER JOIN
(
    SELECT TOP 2 ID, PERIOD,QTY 
    FROM DETAILS D      
    ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID

De bovenstaande zoekopdracht genereert het volgende resultaat.

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-12   |  20   |
x------x---------x--------------x-------x

Zie, het genereerde resultaten voor de laatste twee datums met Idvan de laatste twee datums en voegde deze records vervolgens alleen toe in de buitenste query op Id, wat verkeerd is. Dit zou zowel Ids1 als 2 moeten retourneren, maar er is slechts 1 geretourneerd omdat 1 de laatste twee datums heeft. Om dit te bereiken, moeten we CROSS APPLYgebruiken.

SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
CROSS APPLY
(
    SELECT TOP 2 ID, PERIOD,QTY 
    FROM DETAILS D  
    WHERE M.ID=D.ID
    ORDER BY CAST(PERIOD AS DATE)DESC
)D

en vormt het volgende resultaat.

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-12   |  20   |
|   2  |   B     | 2014-01-08   |  40   |
|   2  |   B     | 2014-01-06   |  30   |
x------x---------x--------------x-------x

Zo werkt het. De query in CROSS APPLYkan verwijzen naar de buitenste tabel, waar inner joindit niet kan doen (het genereert een compileerfout). Bij het vinden van de laatste twee datums, wordt het lidmaatschap gedaan binnen CROSS APPLYd.w.z. WHERE M.ID=D.ID.

2. Wanneer we inner join-functionaliteit nodig hebben met behulp van functies.

CROSS APPLYkan worden gebruikt als vervanging voor inner joinwanneer we een resultaat moeten krijgen van de Master-tabel en een function.

SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
CROSS APPLY dbo.FnGetQty(M.ID) C

En hier is de functie

CREATE FUNCTION FnGetQty 
(   
    @Id INT 
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT ID,PERIOD,QTY 
    FROM DETAILS
    WHERE ID=@Id
)

wat het volgende resultaat opleverde

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-11   |  15   |
|   1  |   A     | 2014-01-12   |  20   |
|   2  |   B     | 2014-01-06   |  30   |
|   2  |   B     | 2014-01-08   |  40   |
x------x---------x--------------x-------x

EXTRA VOORDEEL VAN CROSS APPLY

APPLYkan worden gebruikt als vervanging voor UNPIVOT. Hier kunnen ofwel CROSS APPLYof OUTER APPLYworden gebruikt, die onderling uitwisselbaar zijn.

Bedenk dat je de onderstaande tabel hebt (genaamd MYTABLE).

x------x-------------x--------------x
|  Id  |   FROMDATE  |   TODATE     |
x------x-------------x--------------x
|   1  |  2014-01-11 | 2014-01-13   | 
|   1  |  2014-02-23 | 2014-02-27   | 
|   2  |  2014-05-06 | 2014-05-30   | 
|   3  |     NULL    |    NULL      |
x------x-------------x--------------x

De vraag staat hieronder.

SELECT DISTINCT ID,DATES
FROM MYTABLE 
CROSS APPLY(VALUES (FROMDATE),(TODATE))
COLUMNNAMES(DATES)

wat het resultaat oplevert

 x------x-------------x
  | Id   |    DATES    |
  x------x-------------x
  |  1   |  2014-01-11 |
  |  1   |  2014-01-13 |
  |  1   |  2014-02-23 |
  |  1   |  2014-02-27 |
  |  2   |  2014-05-06 |
  |  2   |  2014-05-30 | 
  |  3   |    NULL     | 
  x------x-------------x

Antwoord 3, autoriteit 29%

Met

CROSS APPLYkun je soms dingen doen die je niet kunt doen met inner join.

Voorbeeld (een syntaxisfout):

select F.* from sys.objects O  
inner join dbo.myTableFun(O.name) F   
on F.schema_id= O.schema_id

Dit is een syntaxisfout, omdat, bij gebruik met inner join, tabelfuncties alleen variabelen of constantenals parameters kunnen gebruiken. (D.w.z. de tabelfunctieparameter kan niet afhankelijk zijn van de kolom van een andere tabel.)

Echter:

select F.* from sys.objects O  
cross apply ( select * from dbo.myTableFun(O.name) ) F  
where F.schema_id= O.schema_id

Dit is legaal.

Bewerken:
Of anders een kortere syntaxis: (door ErikE)

select F.* from sys.objects O  
cross apply dbo.myTableFun(O.name) F
where F.schema_id= O.schema_id

Bewerken:

Opmerking:
Informix 12.10 xC2+ heeft later afgeleide tabellen en Postgresql (9.3+) heeft Laterale subquery’sdie voor een soortgelijk effect kunnen worden gebruikt.


Antwoord 4, autoriteit 6%

Het lijkt mij dat CROSS APPLY een bepaalde leemte kan opvullen bij het werken met berekende velden in complexe/geneste zoekopdrachten, en ze eenvoudiger en leesbaarder kan maken.

Eenvoudig voorbeeld: u hebt een DoB en u wilt meerdere leeftijdsgerelateerde velden presenteren die ook afhankelijk zijn van andere gegevensbronnen (zoals werkgelegenheid), zoals Age, AgeGroup, AgeAtHiring, MinimumRetirementDate, enz. voor gebruik aan uw einde -gebruikerstoepassing (bijvoorbeeld Excel-draaitabellen).

Opties zijn beperkt en zelden elegant:

  • JOIN-subquery’s kunnen geen nieuwe waarden in de dataset introduceren op basis van gegevens in de bovenliggende query (deze moet op zichzelf staan).

  • UDF’s zijn netjes, maar traag omdat ze de neiging hebben om parallelle bewerkingen te voorkomen. En een aparte entiteit zijn kan een goede zaak zijn (minder code) of een slechte zaak (waar is de code).

  • Verbindingstabellen. Soms kunnen ze werken, maar al snel sluit je je aan bij subquery’s met tonnen UNION’s. Grote puinhoop.

  • Maak nog een weergave voor één doel, ervan uitgaande dat er voor uw berekeningen geen gegevens nodig zijn die halverwege uw hoofdquery zijn verkregen.

  • Tussentabellen. Ja … dat werkt meestal, en vaak een goede optie omdat ze kunnen worden geïndexeerd en snel, maar de prestaties kunnen ook afnemen omdat UPDATE-instructies niet parallel zijn en het niet toestaan om formules (hergebruikresultaten) te laten vallen om verschillende velden binnen de dezelfde verklaring. En soms wil je dingen gewoon in één keer doen.

  • query’s nesten. Ja, u kunt op elk moment haakjes op uw hele query plaatsen en deze gebruiken als een subquery waarop u zowel brongegevens als berekende velden kunt manipuleren. Maar je kunt dit alleen zo vaak doen voordat het lelijk wordt. Heel lelijk.

  • Herhalende code. Wat is de grootste waarde van 3 lange (CASE…ELSE…END) statements? Dat wordt leesbaar!

    • Zeg tegen je klanten dat ze die verdomde dingen zelf moeten berekenen.

Heb ik iets gemist? Waarschijnlijk, dus voel je vrij om commentaar te geven. Maar goed, CROSS APPLY is een uitkomst in zulke situaties: je voegt gewoon een simpele CROSS APPLY (select tbl.value + 1 as someFormula) as crossTblen voilà! Uw nieuwe veld is nu klaar voor gebruik, praktisch alsof het er altijd al was geweest in uw brongegevens.

Waarden geïntroduceerd via CROSS APPLY kunnen…

  • worden gebruikt om een of meerdere berekende velden te maken zonder prestatie-, complexiteits- of leesbaarheidsproblemen toe te voegen
  • net als bij JOINs kunnen verschillende opeenvolgende CROSS APPLY-instructies naar zichzelf verwijzen: CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
  • u kunt waarden gebruiken die zijn geïntroduceerd door een CROSS APPLY in volgende JOIN-voorwaarden
  • Als bonus is er het functie-aspect Tabelwaarde

Verdorie, ze kunnen niets doen!


Antwoord 5, autoriteit 2%

Dit is technisch al heel goed beantwoord, maar laat me een concreet voorbeeld geven van hoe het uiterst nuttig is:

Stel dat u twee tabellen heeft, Klant en Bestelling. Klanten hebben veel bestellingen.

Ik wil een weergave maken met details over klanten en de meest recente bestelling die ze hebben gedaan. Met alleen JOINS zou dit wat self-joins en aggregatie vereisen, wat niet mooi is. Maar met Cross Apply is het supereenvoudig:

SELECT *
FROM Customer
CROSS APPLY (
  SELECT TOP 1 *
  FROM Order
  WHERE Order.CustomerId = Customer.CustomerId
  ORDER BY OrderDate DESC
) T

Antwoord 6, autoriteit 2%

Cross apply werkt ook goed met een XML-veld. Als u knooppuntwaarden wilt selecteren in combinatie met andere velden.

Als u bijvoorbeeld een tabel heeft met daarin wat xml

<root>
    <subnode1>
       <some_node value="1" />
       <some_node value="2" />
       <some_node value="3" />
       <some_node value="4" />
    </subnode1>
</root>

De zoekopdracht gebruiken

SELECT
       id as [xt_id]
      ,xmlfield.value('(/root/@attribute)[1]', 'varchar(50)') root_attribute_value
  ,node_attribute_value = [some_node].value('@value', 'int')
  ,lt.lt_name   
FROM dbo.table_with_xml xt
CROSS APPLY xmlfield.nodes('/root/subnode1/some_node') as g ([some_node])
LEFT OUTER JOIN dbo.lookup_table lt
ON [some_node].value('@value', 'int') = lt.lt_id

Retourneert een resultaat

xt_id root_attribute_value node_attribute_value lt_name
----------------------------------------------------------------------
1     test1            1                    Benefits
1     test1            4                    FINRPTCOMPANY

Antwoord 7

Kruis toepassen kan worden gebruikt om subquery’s te vervangen waar u een kolom van de subquery nodig heeft

subquery

select * from person p where
p.companyId in(select c.companyId from company c where c.companyname like '%yyy%')

hier kan ik de kolommen van de bedrijfstabel niet selecteren
dus, kruis toepassen

select P.*,T.CompanyName
from Person p
cross apply (
    select *
    from Company C
    where p.companyid = c.companyId and c.CompanyName like '%yyy%'
) T

Antwoord 8

Ik denk dat het leesbaarheid moet zijn 😉

CROSS APPLY zal enigszins uniek zijn voor mensen die lezen om hen te vertellen dat er een UDF wordt gebruikt die wordt toegepast op elke rij uit de tabel aan de linkerkant.

Natuurlijk zijn er andere beperkingen waarbij een CROSS APPLY beter wordt gebruikt dan JOIN die andere vrienden hierboven hebben gepost.


Antwoord 9

Hier is een artikel dat het allemaal uitlegt, met hun prestatieverschil en gebruik ten opzichte van JOINS.

SQL Server CROSS APPLY en OUTER APPLY over JOINS

Zoals in dit artikel wordt gesuggereerd, is er geen prestatieverschil tussen beide voor normale samenvoegbewerkingen (INNER EN CROSS).

voer hier de afbeeldingsbeschrijving in

Het gebruiksverschil ontstaat wanneer u een zoekopdracht als deze moet uitvoeren:

CREATE FUNCTION dbo.fn_GetAllEmployeeOfADepartment(@DeptID AS INT)  
RETURNS TABLE 
AS 
RETURN 
   ( 
   SELECT * FROM Employee E 
   WHERE E.DepartmentID = @DeptID 
   ) 
GO 
SELECT * FROM Department D 
CROSS APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)

Dat wil zeggen, als je te maken hebt met functie. Dit kan niet worden gedaan met INNER JOIN, wat de fout zou geven “De meerdelige identifier “D.DepartmentID” kan niet worden gebonden.”Hier wordt de waarde doorgegeven aan de functie als elke rij wordt gelezen. Lijkt me cool. 🙂


Antwoord 10

Hier is een korte tutorial die kan worden opgeslagen in een .sql-bestand en kan worden uitgevoerd in SSMS dat ik voor mezelf heb geschreven om snel mijn geheugen op te frissen over hoe CROSS APPLYwerkt en wanneer te gebruiken:

-- Here's the key to understanding CROSS APPLY: despite the totally different name, think of it as being like an advanced 'basic join'.
-- A 'basic join' gives the Cartesian product of the rows in the tables on both sides of the join: all rows on the left joined with all rows on the right.
-- The formal name of this join in SQL is a CROSS JOIN.  You now start to understand why they named the operator CROSS APPLY.
-- Given the following (very) simple tables and data:
CREATE TABLE #TempStrings ([SomeString] [nvarchar](10) NOT NULL);
CREATE TABLE #TempNumbers ([SomeNumber] [int] NOT NULL);
CREATE TABLE #TempNumbers2 ([SomeNumber] [int] NOT NULL);
INSERT INTO #TempStrings VALUES ('111'); INSERT INTO #TempStrings VALUES ('222');
INSERT INTO #TempNumbers VALUES (111); INSERT INTO #TempNumbers VALUES (222);
INSERT INTO #TempNumbers2 VALUES (111); INSERT INTO #TempNumbers2 VALUES (222); INSERT INTO #TempNumbers2 VALUES (222);
-- Basic join is like CROSS APPLY; 2 rows on each side gives us an output of 4 rows, but 2 rows on the left and 0 on the right gives us an output of 0 rows:
SELECT
    st.SomeString, nbr.SomeNumber
FROM -- Basic join ('CROSS JOIN')
    #TempStrings st, #TempNumbers nbr
    -- Note: this also works:
    --#TempStrings st CROSS JOIN #TempNumbers nbr
-- Basic join can be used to achieve the functionality of INNER JOIN by first generating all row combinations and then whittling them down with a WHERE clause:
SELECT
    st.SomeString, nbr.SomeNumber
FROM -- Basic join ('CROSS JOIN')
    #TempStrings st, #TempNumbers nbr
WHERE
    st.SomeString = nbr.SomeNumber
-- However, for increased readability, the SQL standard introduced the INNER JOIN ... ON syntax for increased clarity; it brings the columns that two tables are
-- being joined on next to the JOIN clause, rather than having them later on in the WHERE clause.  When multiple tables are being joined together, this makes it
-- much easier to read which columns are being joined on which tables; but make no mistake, the following syntax is *semantically identical* to the above syntax:
SELECT
    st.SomeString, nbr.SomeNumber
FROM -- Inner join
    #TempStrings st INNER JOIN #TempNumbers nbr ON st.SomeString = nbr.SomeNumber
-- Because CROSS APPLY is generally used with a subquery, the subquery's WHERE clause will appear next to the join clause (CROSS APPLY), much like the aforementioned
-- 'ON' keyword appears next to the INNER JOIN clause.  In this sense, then, CROSS APPLY combined with a subquery that has a WHERE clause is like an INNER JOIN with
-- an ON keyword, but more powerful because it can be used with subqueries (or table-valued functions, where said WHERE clause can be hidden inside the function).
SELECT
    st.SomeString, nbr.SomeNumber
FROM
    #TempStrings st CROSS APPLY (SELECT * FROM #TempNumbers tempNbr WHERE st.SomeString = tempNbr.SomeNumber) nbr
-- CROSS APPLY joins in the same way as a CROSS JOIN, but what is joined can be a subquery or table-valued function.  You'll still get 0 rows of output if
-- there are 0 rows on either side, and in this sense it's like an INNER JOIN:
SELECT
    st.SomeString, nbr.SomeNumber
FROM
    #TempStrings st CROSS APPLY (SELECT * FROM #TempNumbers tempNbr WHERE 1 = 2) nbr
-- OUTER APPLY is like CROSS APPLY, except that if one side of the join has 0 rows, you'll get the values of the side that has rows, with NULL values for
-- the other side's columns.  In this sense it's like a FULL OUTER JOIN:
SELECT
    st.SomeString, nbr.SomeNumber
FROM
    #TempStrings st OUTER APPLY (SELECT * FROM #TempNumbers tempNbr WHERE 1 = 2) nbr
-- One thing CROSS APPLY makes it easy to do is to use a subquery where you would usually have to use GROUP BY with aggregate functions in the SELECT list.
-- In the following example, we can get an aggregate of string values from a second table based on matching one of its columns with a value from the first
-- table - something that would have had to be done in the ON clause of the LEFT JOIN - but because we're now using a subquery thanks to CROSS APPLY, we
-- don't need to worry about GROUP BY in the main query and so we don't have to put all the SELECT values inside an aggregate function like MIN().
SELECT
    st.SomeString, nbr.SomeNumbers
FROM
    #TempStrings st CROSS APPLY (SELECT SomeNumbers = STRING_AGG(tempNbr.SomeNumber, ', ') FROM #TempNumbers2 tempNbr WHERE st.SomeString = tempNbr.SomeNumber) nbr
-- ^ First the subquery is whittled down with the WHERE clause, then the aggregate function is applied with no GROUP BY clause; this means all rows are
--   grouped into one, and the aggregate function aggregates them all, in this case building a comma-delimited string containing their values.
DROP TABLE #TempStrings;
DROP TABLE #TempNumbers;
DROP TABLE #TempNumbers2;

Antwoord 11

Nou, ik weet niet zeker of dit een reden is om Cross Apply versus Inner Join te gebruiken, maar deze vraag is voor mij beantwoord in een forumbericht met Cross Apply, dus ik weet niet zeker of er een gelijkwaardige methode is met Inner Doe mee:

Create PROCEDURE [dbo].[Message_FindHighestMatches]
-- Declare the Topical Neighborhood
@TopicalNeighborhood nchar(255)

AS
BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
Create table  #temp
(
    MessageID         int,
    Subjects          nchar(255),
    SubjectsCount    int
)
Insert into #temp Select MessageID, Subjects, SubjectsCount From Message
Select Top 20 MessageID, Subjects, SubjectsCount,
    (t.cnt * 100)/t3.inputvalues as MatchPercentage
From #temp 
cross apply (select count(*) as cnt from dbo.Split(Subjects,',') as t1
             join dbo.Split(@TopicalNeighborhood,',') as t2
             on t1.value = t2.value) as t
cross apply (select count(*) as inputValues from dbo.Split(@TopicalNeighborhood,',')) as t3
Order By MatchPercentage desc
drop table #temp

END


Antwoord 12

De essentie van de APPLY-operator is om correlatie toe te staan tussen de linker- en rechterkant van de operator in de FROM-component.

In tegenstelling tot JOIN is de correlatie tussen invoer niet toegestaan.

Over correlatie gesproken in de APPLY-operator, ik bedoel, aan de rechterkant kunnen we plaatsen:

  • een afgeleide tabel – als een gecorreleerde subquery met een alias
  • een functie met tabelwaarde – een conceptuele weergave met parameters, waarbij de parameter naar de linkerkant kan verwijzen

Beide kunnen meerdere kolommen en rijen retourneren.


Antwoord 13

Dit is misschien een oude vraag, maar ik ben nog steeds dol op de kracht van CROSS APPLY om het hergebruik van logica te vereenvoudigen en om een “keten”-mechanisme voor resultaten te bieden.

Ik heb hieronder een SQL Fiddle gegeven die een eenvoudig voorbeeld laat zien van hoe je CROSS APPLY kunt gebruiken om complexe logische bewerkingen op je dataset uit te voeren zonder dat het helemaal rommelig wordt. Het is niet moeilijk om van hieruit meer complexe berekeningen te extrapoleren.

http://sqlfiddle.com/#!3/23862/2


Antwoord 14

Hoewel de meeste query’s die gebruikmaken van CROSS APPLY kunnen worden herschreven met een INNER JOIN, kan CROSS APPLY een beter uitvoeringsplan en betere prestaties opleveren, omdat het de set kan beperken voordat de join plaatsvindt.

Gestolen van Hier

Other episodes