【问题标题】:SQL: Is this JOIN over a player table and a subquery-created high score table the best way to perform this operation?SQL:在玩家表和子查询创建的高分表上进行 JOIN 是执行此操作的最佳方式吗?
【发布时间】:2016-05-24 01:23:48
【问题描述】:

我有一个问题,我相信(未经过全面测试,仅经过健全性检查)可行,但对我来说似乎令人难以置信的过度劳累。这是三个表的连接。

一个表是一个包含 questID、playerID 和 score 的任务表。另一张桌子是包含玩家所在区域的玩家桌子。第三张桌子不是真正的桌子;这是一个子查询,它会产生一个临时结果,该结果由每个地区得分最高的玩家组成。

SELECT 
    Q1.QuestID, Q1.PersonID, C1.TerritoryID
FROM 
    [dbo].[T_QuestSys_Quest] AS Q1
JOIN 
    [GZ_GAME].[dbo].[T_Character] AS C1 ON Q1.PersonID = C1.PersonID
JOIN
    (SELECT 
         TerritoryID, MAX(Score) AS HighScore
     FROM 
         [GZ_GAME].[dbo].[T_QuestSys_Quest] AS Q2
     JOIN 
         [GZ_GAME].[dbo].[T_Character] AS C2 ON Q2.PersonID = C2.PersonID 
                                             AND Q2.QuestID = @QuestID
     GROUP BY 
         TerritoryID) AS S ON Q1.Score = S.HighScore 
                           AND C1.TerritoryID = S.TerritoryID 
                           AND Q1.QuestID = @QuestID

值得注意的是,子查询不允许我在 SELECT 语句中添加其他术语,从而导致错误:

在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中”)。

在我看来,MAX(Score) 足以消除我想要的 PersonID 的歧义,但我想不是。

无论如何,我的问题是:在优雅/简单方面有没有更好的方法来做到这一点?就性能而言,有没有更好的方法来做到这一点?

【问题讨论】:

    标签: sql-server join sql-server-2014


    【解决方案1】:

    一种方法使用ROW_NUMBER窗口函数

    ;WITH cte 
         AS (SELECT *,Rwo_number()OVER(partition BY territoryid ORDER BY score DESC) RN
             FROM   [GZ_GAME].[dbo].[t_questsys_quest] AS Q2 
                    JOIN [GZ_GAME].[dbo].[t_character] AS C2 
                      ON Q2.personid = C2.personid 
                         AND Q2.questid = @QuestID) 
    SELECT * 
    FROM   cte 
    WHERE  rn = 1 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      • 2022-06-15
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      相关资源
      最近更新 更多