2

我有两张桌子,Player 和 Shot。Player 和 Shot 之间存在一对多的关系。我想获取一些球员信息,如电子邮件、名字和姓氏,以及球员的最佳射门信息,其中包含各个部分——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

这几乎与我需要的相同,但它返回与最高分并列的每一行。让它返回一行反而令人沮丧。

谢谢你的时间。

4

4 回答 4

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
于 2013-09-03T16:05:33.300 回答
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
于 2013-09-03T16:06:19.063 回答
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 演示,您可以检查性能。

于 2013-09-03T16:13:33.680 回答
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
于 2013-09-03T16:05:42.043 回答