我有两张桌子,Player和Shot。 Player和Shot之间存在1对多的关系。我想获得一些玩家信息,比如Email,FirstName和LastName,以及玩家的头号信息,其中包含各种部分 - CalculatedScore,AccuracyScore,DistanceScore和TimeScore。 CalculatedScore是最重要的值。所有其他都是该分数的组成部分。
这是我的最大努力:
<!-- language: lang-sql -->
select s_max.PlayerId as playerId_max, s_max.TopScore, s.PlayerId, p.FirstName,
p.LastName, s.CalculatedScore, s.AccuracyScore, s.TimeScore, s.DistanceScore from Player p
inner join Shot s on s.PlayerId = p.Id
inner join (
select distinct MAX(CalculatedScore) over (partition by PlayerId) as TopScore,
PlayerId from Shot s2
) s_max on s.PlayerId = s_max.PlayerId and s.CalculatedScore = s_max.TopScore
order by PlayerId desc
这与我需要的几乎完全相同,但它会返回与最高分相关的每一行。让它返回一行却令人惊讶地令人沮丧。
感谢您的时间。
答案 0 :(得分:1)
如果我理解正确,这就是你想要的:
;WITH CTE AS
(
SELECT *,
RN=ROW_NUMBER() OVER(PARTITION BY PlayerId
ORDER BY CalculatedScore DESC)
FROM Shot
)
SELECT A.PlayerId as playerId_max,
B.TopScore,
A.FirstName,
A.LastName,
B.CalculatedScore,
B.AccuracyScore,
B.TimeScore,
B.DistanceScore
FROM Player A
INNER JOIN CTE B
ON A.PlayerId = B.PlayerId
WHERE B.RN = 1
答案 1 :(得分:1)
您可以使用row_number()
代替(获得一行)。此外,使用窗口函数时不需要额外的连接:
select s.PlayerId , s.TopScore, s.PlayerId, p.FirstName,
p.LastName, s.CalculatedScore, s.AccuracyScore, s.TimeScore, s.DistanceScore
from Player p inner join
(select s.*,
row_number() over (partition by s.PleryId order by CalculatedScore desc
) as seqnum
from Shot s
) s
on s.PlayerId = p.Id and seqnum = 1
order by s.PlayerId desc
答案 2 :(得分:1)
我认为这是使用outer/cross apply
的好例子。这应该比使用窗口函数更好,特别是如果Player
表的行数很少:
select
p.Id, p.FirstName, p.LastName,
s.CalculatedScore, s.AccuracyScore, s.TimeScore, s.DistanceScore
from Player as p
outer apply (
select top 1 s.*
from Shot as s
where s.PlayerId = p.Id
order by s.CalculatedScore desc
) as s
这里有sql fiddle demo示例,您可以查看效果。
答案 3 :(得分:0)
您可以使用ROW_NUMBER()
功能:
SELECT *
FROM (select s_max.PlayerId as playerId_max
, s_max.TopScore
, s.PlayerId
, p.FirstName
, p.LastName
, s.CalculatedScore
, s.AccuracyScore
, s.TimeScore
, s.DistanceScore
, ROW_NUMBER() OVER(PARTITION BY PlayerID ORDER BY CalculatedScore DESC)'RowRank'
from Player p
inner join Shot s
on s.PlayerId = p.Id
order by PlayerId desc
)sub
WHERE RowRank = 1