交叉应用表值函数
一个真正的头脑弯曲在这里家伙!
我有一张表,基本上把用户放在一个联盟中:
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
League_EntryID是这里唯一的字段,但您会看到此查询返回该用户输入的当天的多个联赛。
我还有一个表值函数,它返回联盟当前的奖品排名,并且接受联盟ID作为参数,并返回有资格获得奖金的人。 这是一个复杂的功能,理想情况下我希望继续作为接受联盟ID的功能。 结果如下:
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
基本上我想要做的是将表值函数加入到最顶层的查询中,通过传入联盟ID来本质上更新该联盟_实体ID的奖品字段,即
SELECT * FROM [League]
INNER JOIN [League_Entry] ON [League].[LeagueID] = [League_Entry].[LeagueID]
INNER JOIN [dbo].[GetPrizesForLeague]([League].[LeagueID]) ....
我不确定是否可以在这里使用CROSS APPLY,但基本上我相信我需要加入联盟ID和League_EntryID才能为我赢得奖品。 无法访问一个标量函数,然后调用表值函数并从中获取Prize,无法确定最佳方式。
速度在这里让我担心。
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]
任何方向将不胜感激。
您需要使用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
CROSS APPLY / OUTER APPLY的表现非常好。 替换一些内部查询和游标是很好的。
链接地址: http://www.djcxy.com/p/27769.html