交叉应用表值函数

CR4*_*G14 7 sql sql-server sql-server-2008-r2

一个真正的心灵弯曲在这里伙计们!

我有一张桌子,基本上可以在一个联盟中定位用户:

LeagueID Stake  League_EntryID  UserID  TotalPoints TotalBonusPoints    Prize
13028   2.00        58659        2812       15           5              NULL
13028   2.00        58662        3043       8            3              NULL
13029   5.00        58665        2812       8            3              NULL
Run Code Online (Sandbox Code Playgroud)

League_EntryID是此处的唯一字段,但您将看到此查询返回用户当天输入的多个联赛.

我还有一个表值函数,它返回联盟的当前奖励积分,并接受LeagueID作为参数并返回有资格获得奖金的人.这是一个复杂的函数,理想情况下我想保留作为接受LeagueID的函数.结果如下:

UserID  Position    League_EntryID  WinPerc     Prize
2812    1               58659       36.000000   14.00
3043    6               58662       2.933333    4.40
3075    6               58664       2.933333    4.40
Run Code Online (Sandbox Code Playgroud)

基本上我想要做的是通过传入LeagueID来将表值函数连接到最顶层的查询,以基本上更新该League_EntryID的奖励字段,即

SELECT * FROM [League]
INNER JOIN [League_Entry] ON [League].[LeagueID] = [League_Entry].[LeagueID]
INNER JOIN [dbo].[GetPrizesForLeague]([League].[LeagueID]) ....
Run Code Online (Sandbox Code Playgroud)

我不确定CROSS APPLY是否可以在这里工作,但基本上我相信我需要在LeagueID和League_EntryID上加入我的奖金给我的价值.不知道如何在没有访问标量函数的情况下执行此操作,该标量函数将依次调用表值函数并从中获取奖励.

速度让我担心.

PS并非所有League_EntryID都将作为表值函数输出的一部分存在,因此可以使用OUTER JOIN/APPLY吗?

编辑请参阅下面的查询

SELECT DISTINCT [LeagueID],
    [CourseName],
    [Refunded],
   [EntryID],
   [Stake],
   d.[League_EntryID],
   d.[UserID],
   [TotalPoints],
   [TotalBonusPoints],
   [TotalPointsLastRace],
   [TotalBonusPointsLastRace],
   d.[Prize],
   [LeagueSizeID],
   [TotalPool],
   d.[Position],
   [PositionLastRace],
   t.Prize

FROM
(
SELECT [LeagueID],
   [EntryID],
   [Stake],
   [MeetingID],
   [Refunded],
   [UserID],
   [League_EntryID],
   [TotalPoints],
   [TotalBonusPoints],
   [TotalPointsLastRace],
   [TotalBonusPointsLastRace],
   [Prize],
   [LeagueSizeID],
   [dbo].[GetTotalPool]([LeagueID], 1) AS [TotalPool],
   RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC) AS [Position],
   RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPointsLastRace] DESC, [TotalBonusPointsLastRace] DESC) AS [PositionLastRace],
   ROW_NUMBER() OVER (PARTITION BY [LeagueID]
                                ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC
                               ) as [Position_Rownum]
FROM [DATA] ) AS d

INNER JOIN [Meeting] WITH (NOLOCK)  ON [d].[MeetingID] = [Meeting].[MeetingID]
INNER JOIN [Course] ON [Meeting].[CourseID] = [Course].[CourseID]
OUTER APPLY (SELECT * FROM [dbo].[GetLeaguePrizes](d.[LeagueID])) t
WHERE (
        ([LeagueSizeID] = 3 AND [Position_Rownum] <= 50)
        OR (d.[UserID] = @UserID AND [LeagueSizeID] = 3)
      )
      OR
      (
        [LeagueSizeID] in (1,2)
      )

ORDER BY [LeagueID], [Position]  
Run Code Online (Sandbox Code Playgroud)

任何方向将不胜感激.

Fra*_*ein 3

您需要使用 OUTER APPLY(CROSS APPLY 和 LEFT JOIN 的混合)。

SELECT * FROM [League]
INNER JOIN [League_Entry] ON [League].[LeagueID] = [League_Entry].[LeagueID]
OUTER APPLY [dbo].[GetPrizesForLeague]([League].[LeagueID]) t 
Run Code Online (Sandbox Code Playgroud)

交叉应用/外部应用的性能非常好。它非常适合替换一些内部查询和游标。