අභ්‍යන්තර සම්බන්ධතාවයට වඩා හරස් අයදුම් කළ යුත්තේ කවදාද?


936

CROSS APPLY භාවිතා කිරීමේ ප්‍රධාන අරමුණ කුමක්ද?

cross applyඔබ කොටස් කර ඇත්නම් විශාල දත්ත කට්ටල තෝරාගැනීමේදී වඩාත් කාර්යක්ෂම විය හැකි (නොපැහැදිලි ලෙස, අන්තර්ජාලයේ පළ කිරීම් හරහා) මම කියවා ඇත්තෙමි . (පේජිං මතකයට එයි)

CROSS APPLYදකුණු වගුව ලෙස UDF අවශ්‍ය නොවන බව මම දනිමි .

බොහෝ INNER JOINවිමසුම් වලදී (එක් සිට බොහෝ සම්බන්ධතා දක්වා), මට ඒවා නැවත භාවිතා කිරීමට භාවිතා කළ හැකි CROSS APPLYනමුත් ඒවා සෑම විටම මට සමාන ක්‍රියාත්මක කිරීමේ සැලසුම් ලබා දෙයි.

CROSS APPLYඑවැනි අවස්ථාවන්හි වෙනසක් සිදු වන්නේ කවදාද යන්න පිළිබඳව මට හොඳ උදාහරණයක් ලබා දිය හැකිද INNER JOIN?


සංස්කරණය කරන්න:

මෙන්න ඉතා සුළු උදාහරණයක්, ක්‍රියාත්මක කිරීමේ සැලසුම් හරියටම සමාන වන තැන. (ඒවා එකිනෙකට වෙනස් හා cross applyවේගවත් / වඩා කාර්යක්ෂම තැනක් මට පෙන්වන්න )

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

50
මම දන්නවා මෙය මගේ EVEN PICKIER නමුත් 'රංගන ශිල්පියා' යනු නියත වශයෙන්ම වචනයකි. එය කාර්යක්ෂමතාවයට සම්බන්ධ නොවේ.
Rire1979

2
වර්ග xquery සඳහා එය ඉතා ප්‍රයෝජනවත් වේ. මෙය පරීක්ෂා කරන්න .
ARZ

3
"අභ්‍යන්තර ලූප් එක්වීම" භාවිතා කිරීම හරස් යෙදුමට ඉතා ආසන්න බව පෙනේ. එක්වන ඉඟිය සමාන වන ඔබේ උදාහරණය සවිස්තරාත්මක යැයි මම ප්‍රාර්ථනා කරමි. එක්වීම යැයි පැවසීමෙන් අභ්‍යන්තර / ලූප / ඒකාබද්ධ වීමට හෝ "වෙනත්" වීමට පවා ඉඩ ඇත.
crokusek

3
සම්බන්ධ වීම පේළි විශාල ප්‍රමාණයක් නිර්මාණය කරන නමුත් ඔබට අවශ්‍ය වන්නේ වරකට එක් පේළි බැඳීමක් පමණක් ඇගයීමට ලක් කිරීම පමණි. පේළි මිලියන 100 කට වඩා වැඩි මේසයක් මත ස්වයං සම්බන්ධතාවයක් අවශ්‍ය වූ අතර මට ප්‍රමාණවත් තරම් මතකයක් නොතිබුණි. ඒ නිසා මම කර්සරයට ගියේ මතක අඩිපාර පහළට ගෙන ඒමටයි. කර්සරයේ සිට මම තවමත් කළමනාකරණය කළ මතක අඩිපාර ලෙස හරස් අයදුම් කළ අතර එය කර්සරයට වඩා 1/3 වේගවත් විය.
පැපරාසෝ

10
CROSS APPLYකට්ටලයක් තවත් එකක් මත යැපීමට ඉඩ දීමේදී එහි පැහැදිලි භාවිතයක් ඇත ( JOINක්‍රියාකරු මෙන් නොව ), නමුත් එය පිරිවැයකින් තොරව එන්නේ නැත: එය හැසිරෙන්නේ වම් කට්ටලයේ සෑම සාමාජිකයෙකුටම වඩා ක්‍රියාත්මක වන ශ්‍රිතයක් ලෙස ය , එබැවින් SQL සේවාදායකය අනුව එය සෑම විටම සිදු කරන්න Loop Join, එය කිසි විටෙකත් කට්ටලවලට සම්බන්ධ වීමට හොඳම ක්‍රමය නොවේ. එබැවින්, APPLYඔබට අවශ්‍ය විටදී භාවිතා කරන්න, නමුත් එය අධික ලෙස භාවිතා නොකරන්න JOIN.
ජෙරාර්ඩෝ ලීමා

Answers:


677

INNER JOIN වැඩ කරන අවස්ථා වලදී CROSS APPLY විසින් වෙනසක් සිදු කරන විට මට හොඳ උදාහරණයක් ලබා දිය හැකිද?

සවිස්තරාත්මක කාර්ය සාධනය සංසන්දනය සඳහා මගේ බ්ලොග් අඩවියේ ලිපිය බලන්න:

CROSS APPLYසරල JOINතත්වයක් නොමැති දේවල් මත වඩා හොඳින් ක්‍රියා කරයි .

මෙය එක් එක් වාර්තාව සඳහා 3අවසාන වාර්තා තෝරා ගන්නේ :t2t1

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

එය INNER JOINකොන්දේසියක් සමඟ පහසුවෙන් සකස් කළ නොහැක .

CTEකවුළු සහ කවුළු ශ්‍රිතය භාවිතයෙන් ඔබට එවැනි දෙයක් කළ හැකිය :

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

, නමුත් මෙය අඩු කියවිය හැකි සහ කාර්යක්ෂමතාව අඩුය.

යාවත්කාලීන කිරීම:

පරීක්ෂා කර ඇත.

masterයනු ඔන් 20,000,000සමඟ වාර්තා පිළිබඳ වගුවකි .PRIMARY KEYid

මෙම විමසුම:

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

30තත්පරයකට ආසන්න කාලයක් ධාවනය වන අතර මෙය:

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

ක්ෂණිකයි.


2
ඒරියල්ගේ සබැඳියේ අවසානය බලන්න. පේළි_ සංඛ්‍යා () විමසුමක් ඉතා හොඳයි, එයට සම්බන්ධ වීමට පවා අවශ්‍ය නොවේ. එබැවින් මෙම තත්වය සඳහා මම හරස් අයදුම් භාවිතා කළ යුතු යැයි මම නොසිතමි (ඉහළ 3 තෝරන්න, t1.id අනුව කොටස).
ජෙෆ් මීට්බෝල් යැං

380
මෙය වඩාත්ම ජනප්‍රිය පිළිතුර වුවද එය සත්‍ය ප්‍රශ්නයට පිළිතුරු සපයනු ඇතැයි මම නොසිතමි. "CROSS APPLY භාවිතා කිරීමේ ප්‍රධාන අරමුණ කුමක්ද?". ප්‍රධාන පරමාර්ථය වන්නේ පරාමිතීන් සහිත වගු කාර්යයන් පේළියකට එක් වරක් ක්‍රියාත්මක කර ප්‍රති .ල සමඟ සම්බන්ධ කිරීමයි.
මයික්කුල්ස්

5
Ike මයික්: ඔබ TVFසමඟ අමතන්නේ කෙසේද INNER JOIN?
ක්වාස්නෝයි

15
IkeMikeKulls ඔව්, නමුත් OP භාවිතා කිරීමේ ප්‍රධාන අරමුණ ඉල්ලා නොසිටි CROSS APPLYඅතර INNER JOIN, එය තෝරා ගන්නේ කවදාද, එයද ක්‍රියාත්මක වන්නේ කවදාදැයි ඔහු ඉල්ලා සිටියේය .
එරික්

8
මෙය lateral joinසම්මත (ANSI) SQL ලෙස
හැඳින්වීම වටී.

200

cross applyසමහර විට ඔබට කළ නොහැකි දේවල් කිරීමට ඔබට හැකියාව ලැබේ inner join.

උදාහරණය (සින්ටැක්ස් දෝෂයක්):

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

මෙය සින්ටැක්ස් දෝෂයකි , මන්ද, භාවිතා කරන විට inner join, වගු ක්‍රියාකාරිත්වයට විචල්‍යයන් හෝ නියතයන් පරාමිතීන් ලෙස පමණක් ගත හැකිය . (එනම්, වගු ශ්‍රිත පරාමිතිය වෙනත් වගුවක තීරුව මත රඳා පැවතිය නොහැක.)

කෙසේවෙතත්:

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

මෙය නීත්‍යානුකූලයි.

සංස්කරණය කරන්න: නැතහොත් විකල්පයක් ලෙස කෙටි වාක්‍ය ඛණ්ඩය: (එරික් විසින්)

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

සංස්කරණය කරන්න:

සටහන: ඉන්ෆොමික්ස් 12.10 xC2 + හි පාර්ශ්වීය ව්‍යුත්පන්න වගු ඇති අතර Postgresql (9.3+) හි පාර්ශ්වීය අනුකාරක ඇත, එය සමාන බලපෑමක් සඳහා භාවිතා කළ හැකිය.


11
මම හිතන්නේ අපට හරස් අයදුම් කිරීමට හේතුව මෙයයි. ඔබ පහත සබැඳිය පරීක්ෂා කර බැලුවහොත් හරස් යෙදුම ගැන එම්එස් පවසන පළමු දෙය මෙයයි. එයට වෙනත් භාවිතයන් තිබිය හැකි නමුත් එය හඳුන්වා දීමට හේතුව මෙය යැයි මම සිතමි. එය නොමැතිව වගු කාර්යයන් බොහෝ අවස්ථාවන්හිදී භාවිතා කළ නොහැක. technet.microsoft.com/en-us/library/ms175156.aspx
මයික්කුල්ස්

හරස් යෙදුම මඟින් අවශ්‍ය කරන මොඩියුලරිටි පවත්වා ගනිමින් පේළිගත කිරීමේ වගු කාර්යයන් සමඟ සම්බන්ධ වන විට හොඳ ක්‍රියාත්මක කිරීමේ සැලැස්මක් ද නිපදවයි.
නියුරෙටින්

15
SELECTඇතුළත අවශ්‍ය නොවේ CROSS APPLY. කරුණාකර උත්සාහ කරන්න CROSS APPLY dbo.myTableFun(O.name) F.
එරික්

1
Ri එරික් විශ්වාසයි, ඔබට සෑම විටම අඩු නම්යශීලී සින්ටැක්ස් භාවිතා කර හරස් යෙදුම භාවිතා කළ හැකිය. විමසුමට තීරු ගණනය කිරීම අසීරු වීම වළක්වා ගැනීම සඳහා ඔබට සමහර විට භාවිතා කළ හැකි වඩාත් සාමාන්‍යකරණය කළ අනුවාදය මම පෙන්වමින් සිටියෙමි.
නුරෙටින්

2
තේරීම් වගුවේ පරාමිතිය බාහිර තේරීමේදී වෙනත් වගුවක තීරුව (බාහිර යොමු) මත රඳා පවතී නම් බොලු අභ්‍යන්තර සම්බන්ධ වීම ක්‍රියා නොකරනු ඇත. වගු ශ්‍රිත පරාමිතිය වචනානුසාරයෙන් හෝ විචල්‍යයක් නම් එය ක්‍රියා කරයි. හරස් අයදුම් කිරීම අවස්ථා දෙකේදීම ක්‍රියාත්මක වේ.
නියුරෙටින්

176

ඔබට මේස දෙකක් ඇති බව සලකන්න.

මාස්ටර් වගුව

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

විස්තර වගුව

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

අප විසින් ප්රතිස්ථාපනය INNER JOINකළ යුතු අවස්ථා බොහොමයක් තිබේ CROSS APPLY.

මත පදනම් වූ වගු දෙකක් එකතු වන්න 1. TOP nප්රතිඵල

අපි තෝරා ගැනීමට අවශ්ය නම් සලකා බලන්න Idසහ Nameසිට Masterඑක් එක් සඳහා පසුගිය දින දෙකක් Idසිට 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

ඉහත විමසුම පහත ප්‍රති .ලය ජනනය කරයි.

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

බලන්න, එය අවසාන දින දෙක සමඟ අවසාන දින දෙක සඳහා ප්‍රති results ල ජනනය කළ Idඅතර පසුව මෙම වාර්තා සමඟ සම්බන්ධ වූයේ පිටත විමසුමේදී පමණි Id, එය වැරදිය. මෙය Ids1 සහ 2 යන දෙකම ආපසු ලබා දිය යුතු නමුත් එය ආපසු පැමිණියේ 1 ක් පමණි, මන්ද 1 ට අවසාන දින දෙක ඇත. මෙය ඉටු කිරීම සඳහා අප භාවිතා කළ CROSS APPLYයුතුය.

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

සහ පහත ප්‍රති .ලය සාදයි.

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

මෙන්න එය ක්‍රියාත්මක වන ආකාරය. ඇතුළත විමසුමට CROSS APPLYපිටත වගුව යොමු කළ හැකිය, එහිදී මෙය INNER JOINකළ නොහැක (එය සම්පාදක දෝෂයක් විසි කරයි). අවසාන දින දෙක සොයා ගැනීමේදී, සම්බන්ධ වීම සිදු වන්නේ CROSS APPLYඑනම් , WHERE M.ID=D.ID.

2. අපට INNER JOINශ්‍රිත භාවිතා කරමින් ක්‍රියාකාරීත්වය අවශ්‍ය වූ විට .

CROSS APPLYඅපට වගුවෙන් ප්‍රති a INNER JOINල ලබා ගැනීමට අවශ්‍ය වූ විට ආදේශකයක් ලෙස භාවිතා කළ හැකිය .Masterfunction

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

මෙන්න කාර්යය

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

එය පහත ප්‍රති .ලය ජනනය කළේය

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

හරස් ඉල්ලුමේ අතිරේක දියුණුව

APPLYවෙනුවට ආදේශකයක් ලෙස භාවිතා කළ හැකිය UNPIVOT. එක්කෝ CROSS APPLYහෝ OUTER APPLYමෙහි භාවිතා කළ හැකිය, ඒවා එකිනෙකට හුවමාරු වේ.

ඔබට පහත වගුව ඇති බව සලකන්න (නම් කර ඇත 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

විමසුම පහතින්.

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

එය ඔබට ප්‍රති .ලය ගෙන එයි

  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

4
2 එදිරිව 4 වාර්තා සමඟ ඇති විශිෂ්ට උදාහරණය සහ මෙය අවශ්‍ය වන සන්දර්භය තේරුම් ගැනීමට මට උපකාරී විය.
trnelson

13
මෙම පිළිතුර සනාථ කරන්නේ පිළිගත් එකක් තෝරා ගැනීම වෙනුවට පිටුව පහළට අනුචලනය කිරීමයි.
මොස්ටාෆා ආමන්ඩි

2
APPLY භාවිතය පැහැදිලි කිරීම සඳහා මෙතෙක් ලබා දී ඇති හොඳම උදාහරණය ... මම බොහෝ ලිපි කියවා ඇති අතර මෙම පැහැදිලි කිරීම මඟින් පින්තූරය ජලය ලෙස ඉවත් වන බව මට වැටහේ. බොහෝ ස්තූතියි සහෝදරයා.
AG7

1
1 වන ස්ථානය සඳහා පේළි 4 ක් වෙනුවට ID 1 සඳහා පේළි 2 ක් ඇති 1 වන ස්ථානය සඳහා, අපි ඒ වෙනුවට වම් සම්බන්ධතාවයක් භාවිතා නොකරමු.
ජෝශප් චෝ

43

සංකීර්ණ / කැදැලි විමසුම් වල ගණනය කරන ලද ක්ෂේත්‍ර සමඟ වැඩ කිරීමේදී ක්‍රොස් ඇප්ලි හට යම් පරතරයක් පිරවිය හැකි බව මට පෙනේ.

සරල උදාහරණය: ඔබට DoB එකක් ඇති අතර ඔබේ අවසාන පරිශීලක යෙදුමේ භාවිතය සඳහා වයස, වයස් කාණ්ඩය, AgeAtHiring, MinimumRetirementDate වැනි වෙනත් දත්ත ප්‍රභවයන් (රැකියාව වැනි) මත රඳා පවතින වයස් ආශ්‍රිත ක්ෂේත්‍ර කිහිපයක් ඉදිරිපත් කිරීමට ඔබට අවශ්‍යය. (උදාහරණයක් ලෙස එක්සෙල් PivotTables).

විකල්ප සීමිත වන අතර කලාතුරකින් අලංකාර වේ:

  • මව් විමසුමේ දත්ත මත පදනම්ව දත්ත කට්ටලයේ නව අගයන් JOIN උප විමසුම් වලට හඳුන්වා දිය නොහැක (එය තනිවම පැවතිය යුතුය).

  • UDFs පිළිවෙලට ඇති නමුත් සමාන්තර මෙහෙයුම් වලක්වාලීමට මන්දගාමී වේ. වෙනම ආයතනයක් වීම හොඳ (අඩු කේතයක්) හෝ නරක (කේතය කොහේද) විය හැකිය.

  • හන්දිය වගු. සමහර විට ඔවුන්ට වැඩ කළ හැකිය, නමුත් ඉක්මනින් ඔබ යුනියන් ටොන් ගණනක් සමඟ උපසිරැසි වලට සම්බන්ධ වේ. ලොකු අවුලක්.

  • ඔබේ ගණනය කිරීම් සඳහා ඔබේ ප්‍රධාන විමසුම හරහා ලබාගත් දත්ත අවශ්‍ය නොවන බව උපකල්පනය කරමින් තවත් තනි අරමුණු දැක්මක් සාදන්න.

  • අතරමැදි වගු. ඔව් ... එය සාමාන්‍යයෙන් ක්‍රියාත්මක වන අතර බොහෝ විට ඒවා සුචිගත කළ හැකි හා වේගවත් කළ හැකි හොඳ විකල්පයකි, නමුත් යාවත්කාලීන ප්‍රකාශ සමාන්තරව නොතිබීම සහ ක්ෂේත්‍ර කිහිපයක් යාවත්කාලීන කිරීමට සූත්‍ර (ප්‍රති results ල නැවත භාවිතා කිරීම) සඳහා ඉඩ නොදීම හේතුවෙන් කාර්ය සාධනය පහත වැටෙනු ඇත. එකම ප්‍රකාශය. සමහර විට ඔබ එක වරකට දේවල් කිරීමට කැමති වනු ඇත.

  • කැදැලි විමසුම්. ඔව්, ඕනෑම වේලාවක ඔබට ඔබේ සම්පූර්ණ විමසුමට වරහන් ඇතුළත් කළ හැකි අතර එය මූලාශ්‍ර දත්ත සහ ගණනය කළ ක්ෂේත්‍ර එක හා සමානව හැසිරවිය හැකි අනුකාරකයක් ලෙස භාවිතා කළ හැකිය. නමුත් ඔබට මෙය කළ හැක්කේ එය කැත වීමට පෙර පමණි. ඉතා කැත.

  • කේතය නැවත කිරීම. දිගු (CASE ... ELSE ... END) ප්‍රකාශ 3 ක විශාලතම වටිනාකම කුමක්ද? එය කියවිය හැකි වනු ඇත!

    • නපුරු දේ ගණනය කිරීමට ඔබේ සේවාදායකයින්ට කියන්න.

මට යමක් මග හැරුණාද? බොහෝ විට, එබැවින් අදහස් දැක්වීමට නිදහස් වන්න. ඒයි, ක්‍රොස් ඇප්ලි යනු එවැනි අවස්ථාවන්හි දේවතාවියකට සමාන ය: ඔබ සරල CROSS APPLY (select tbl.value + 1 as someFormula) as crossTblහා හ ile ක් එක් කරන්න ! ඔබගේ නව ක්ෂේත්‍රය දැන් ඔබේ ප්‍රභව දත්තවල තිබුනාක් මෙන් ප්‍රායෝගිකව භාවිතයට සූදානම්ය.

CROSS APPLY හරහා හඳුන්වා දුන් අගයන්ට ...

  • මිශ්‍රණයට කාර්ය සාධනය, සංකීර්ණත්වය හෝ කියවීමේ හැකියාව එකතු නොකර ගණනය කළ ක්ෂේත්‍ර එකක් හෝ කිහිපයක් නිර්මාණය කිරීමට භාවිතා කළ හැකිය
  • JOINs මෙන්, පසුකාලීන CROSS APPLY ප්‍රකාශ කිහිපයකට තමන් වෙත යොමු විය හැකිය: CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
  • ඔබට CROS APPLY විසින් හඳුන්වා දුන් අගයන් පසුකාලීන බැඳීම් තත්වයන් තුළ භාවිතා කළ හැකිය
  • ප්‍රසාද දීමනාවක් ලෙස, වගු අගය කළ ශ්‍රිත අංගයක් ඇත

ඩැං, ඔවුන්ට කරන්න බැරි දෙයක් නැහැ!


1
මෙය මගෙන් විශාල +1 ක් වන අතර, එය පුදුමයට කරුණක් බැවින් එය බොහෝ විට සඳහන් නොවේ. ව්‍යුත්පන්න අගයන් දාමය මත "කාර්ය පටිපාටික" ගණනය කිරීම් සිදු කරන්නේ කෙසේදැයි පෙන්වීමට ඔබට මෙම උදාහරණය දිගු කළ හැකිද? උදා: එගොඩ multiTbl (ගුණ වශයෙන් * crossTbl.value තෝරා tbl.multiplier) කරන්න - එගොඩ සහිතක (ව්යුත්පන්න ලෙස multiTbl.Multiplied / tbl.DerivativeRatio තෝරන්න) derivedTbl - ආදිය ...
mrmillsy

1
CASE..ELSE..END වෙනුවට ආදේශකයක් ලෙස Cross Apply භාවිතා කරන්නේ කෙසේද යන්න පිළිබඳ තවත් තොරතුරු / උදාහරණ?
przemo_li

3
Stateprzemo_li APPLY මඟින් සිද්ධි ප්‍රකාශයක ප්‍රති result ලය (වෙනත් දේ අතර) එය යොමු කිරීම සඳහා ගබඩා කිරීමට භාවිතා කළ හැකිය. ව්‍යුහයක් වැනි දෙයක් විය හැකිය: උපවිශේෂය.
mtone

හරස් සමඟ ගණනය කිරීම් සඳහා උදාහරණය col.sql.drylib.com
alpav

14

හරස් යෙදුම XML ක්ෂේත්‍රයක් සමඟ හොඳින් ක්‍රියා කරයි. ඔබට වෙනත් ක්ෂේත්‍ර සමඟ ඒකාබද්ධව නෝඩ් අගයන් තෝරා ගැනීමට අවශ්‍ය නම්.

උදාහරණයක් ලෙස, ඔබට xml අඩංගු වගුවක් තිබේ නම්

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

විමසුම භාවිතා කිරීම

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

ප්‍රති .ලයක් ලබා දෙනු ඇත

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

13

මේ සඳහා දැනටමත් තාක්‍ෂණිකව ඉතා හොඳින් පිළිතුරු ලබා දී ඇත, නමුත් එය අතිශයින්ම ප්‍රයෝජනවත් වන ආකාරය පිළිබඳ ස්ථිර උදාහරණයක් දීමට මට ඉඩ දෙන්න:

ඔබට ගනුදෙනුකරු සහ ඇණවුම දෙකක් ඇති බව කියමු. ගනුදෙනුකරුවන්ට බොහෝ ඇණවුම් තිබේ.

ගනුදෙනුකරුවන් පිළිබඳ විස්තර සහ ඔවුන් විසින් සාදන ලද නවතම ඇණවුම ලබා දෙන දර්ශනයක් නිර්මාණය කිරීමට මට අවශ්‍යය. හුදෙක් JOINS සමඟ, මේ සඳහා ස්වයං-සම්බන්ධතා සහ එකතුවක් අවශ්‍ය නොවන අතර එය ලස්සන නොවේ. නමුත් ක්‍රොස් ඇප්ලී සමඟ, එහි සුපිරි පහසුකම:

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

7

ඔබට අනුකාරකයේ තීරුවක් අවශ්‍ය තැනක ආදේශ කිරීම සඳහා හරස් යෙදුම භාවිතා කළ හැකිය

අනුකාරක

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

මෙහිදී මට හරස් වගුව භාවිතා කරමින් සමාගම් වගුවේ තීරු තෝරා ගැනීමට නොහැකි වනු ඇත

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

5

මම හිතන්නේ එය කියවීමේ හැකියාව විය යුතුයි;)

යූඩීඑෆ් භාවිතා කරන බව කියවීමට කියවීමට මිනිසුන්ට ක්‍රොස් ඇප්ලි තරමක් සුවිශේෂී වනු ඇති අතර එය වම් පස ඇති මේසයේ සිට සෑම පේළියකටම යොදනු ඇත.

වෙනත් මිතුරන් ඉහත පළ කර ඇති JOIN වලට වඩා CROSS APPLY භාවිතා කිරීම සඳහා වෙනත් සීමාවන් තිබේ.


4

JOINS වලට වඩා ඒවායේ ක්‍රියාකාරීත්වයේ වෙනස සහ භාවිතය සමඟ ඒ සියල්ල පැහැදිලි කරන ලිපියක් මෙන්න.

JOINS හරහා SQL Server CROSS APPLY සහ OUTER APPLY

මෙම ලිපියේ යෝජනා කර ඇති පරිදි, සාමාන්‍ය සම්බන්ධ වීමේ මෙහෙයුම් සඳහා (INNER AND CROSS) ඔවුන් අතර කාර්ය සාධන වෙනසක් නොමැත.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඔබට මෙවැනි විමසුමක් කිරීමට සිදු වූ විට භාවිත වෙනස පැමිණේ:

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)

එනම්, ඔබට ශ්‍රිතය සමඟ සම්බන්ධ වීමට සිදු වූ විට. INNER JOIN භාවිතයෙන් මෙය කළ නොහැක, එමඟින් ඔබට දෝෂයක් ලැබෙනු ඇත "බහු-කොටස් හඳුනාගැනීමේ" D.DepartmentID "බැඳිය නොහැක." සෑම පේළියක්ම කියවන විට මෙහි අගය ශ්‍රිතයට ලබා දේ. මට නියමයි. :)


3

හරස් අයදුම් කිරීමට එදිරිව අභ්‍යන්තර සම්බන්ධ වීමට මෙය සුදුසුදැයි මට විශ්වාස නැත, නමුත් මෙම විමසුමට මා හට ෆෝම් පෝස්ට් එකක හරස් යෙදුම භාවිතා කර පිළිතුරු සපයන ලදි, එබැවින් අභ්‍යන්තර සම්බන්ධතාවය භාවිතා කරමින් සමාන ක්‍රමයක් තිබේදැයි මට විශ්වාස නැත:

Create PROCEDURE [dbo].[Message_FindHighestMatches]

-- Declare the Topical Neighborhood
@TopicalNeighborhood nchar(255)

ආරම්භයේදී

-- 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

අවසානය


3

APPLY ක්රියාකරුගේ සාරය නම් FROM වගන්තියේ ක්රියාකරුගේ වම් සහ දකුණු පැත්ත අතර සහසම්බන්ධතාවයට ඉඩ දීමයි.

JOIN ට වෙනස්ව, යෙදවුම් අතර සහසම්බන්ධතාවයට ඉඩ නොදේ.

APPLY ක්රියාකරුගේ සහසම්බන්ධය ගැන කථා කරමින්, මම අදහස් කළේ අපට තැබිය හැකි දකුණු පැත්තේ:

  • ව්‍යුත්පන්න වගුවක් - අන්වර්ථයක් සමඟ සහසම්බන්ධිත අනුකාරකයක් ලෙස
  • වගු වටිනාකමින් යුත් ශ්‍රිතයක් - පරාමිතීන් වම් පැත්තට යොමු කළ හැකි පරාමිතීන් සහිත සංකල්පීය දසුනක්

දෙකම බහු තීරු සහ පේළි ආපසු ලබා දිය හැකිය.


2

මෙය සමහර විට පැරණි ප්‍රශ්නයක් විය හැකි නමුත්, තර්කනය නැවත භාවිතා කිරීම සරල කිරීමට සහ ප්‍රති .ල සඳහා “දම්වැල්” යාන්ත්‍රණයක් සැපයීමට CROSS APPLY හි බලයට මම තවමත් ප්‍රිය කරමි.

මම පහත SQL Fiddle එකක් ලබා දී ඇති අතර එමඟින් ඔබේ දත්ත කට්ටලයේ සංකීර්ණ තාර්කික මෙහෙයුම් සිදු කිරීමට ඔබට ක්‍රොස් ඇප්ලි භාවිතා කළ හැකි ආකාරය පිළිබඳ සරල උදාහරණයක් පෙන්වයි. වඩාත් සංකීර්ණ ගණනය කිරීම් මෙතැන් සිට උපුටා ගැනීම අපහසු නැත.

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


2

CROSS APPLY භාවිතා කරන බොහෝ විමසුම් INNER JOIN භාවිතයෙන් නැවත ලිවිය හැකි අතර, CROSS APPLY හට වඩා හොඳ ක්‍රියාත්මක කිරීමේ සැලැස්මක් සහ වඩා හොඳ කාර්ය සාධනයක් ලබා දිය හැකිය.

මෙතනින් හොරකම් කළා

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.