【问题标题】:multipe group by, count and join多个分组,计数和加入
【发布时间】:2011-08-24 16:15:35
【问题描述】:

我有 3 个表格,看起来像这样:

Table1 用户:

  • 身份证
  • 姓名
  • 得分

桌2游戏:

  • 身份证
  • 姓名
  • 犯规

表 3 游戏 2

  • 身份证
  • 姓名
  • 犯规

我想做的是在 Table1 中选择所有用户。 然后选择 Table1.Name = Table2.Name OR Table1.Name = Table3.Name 但对 Table2 具有更高优先级的所有数据,因此如果存在匹配 Table1.Name = Table2.Name 则不会从表 3 进行连接。然后当我选择正确的时候,我也想计算得分和犯规的总和。

这是如何在 SQL 中完成的,是否可行?我正在使用 MSSQL

【问题讨论】:

    标签: sql sql-server tsql aggregate-functions


    【解决方案1】:
    SELECT
      SUM(t1.Score) AS TotalScore,
      SUM(COALESCE(t2.Fouls, t3.Fouls)) AS TotalFouls
    FROM Table1 t1
      LEFT JOIN Table2 t2 ON t2.Name = t1.Name
      LEFT JOIN Table3 t3 ON t3.Name = NULLIF(t1.Name, t2.Name)
    

    【讨论】:

      【解决方案2】:

      您可以通过在连接到表 3 的条件中指定 Table2.Name IS NULL 来支持表 2 的连接。如果您想要以每位球员为基础的总得分和犯规数,您可以这样做:

      SELECT derived_table.Name, SUM(derived_table.Score), SUM(derived_table.Fouls)
      FROM (
          SELECT Name = Table1.Name, Score = Table1.Score,
              Fouls = COALESCE(Table2.Fouls, Table3.Fouls)
          FROM Table1
              LEFT OUTER JOIN Table2 ON Table2.Name = Table1.Name
              LEFT OUTER JOIN Table3 ON Table3.Name = Table1.Name
                  AND Table2.Name IS NULL
          WHERE Table2.Name IS NOT NULL OR Table3.Name IS NOT NULL
          ) derived_table
      GROUP BY derived_table.Name
      

      总计:

      SELECT SUM(derived_table.Score), SUM(derived_table.Fouls)
      FROM (
          SELECT Score = Table1.Score,
              Fouls = COALESCE(Table2.Fouls, Table3.Fouls)
          FROM Table1
              LEFT OUTER JOIN Table2 ON Table2.Name = Table1.Name
              LEFT OUTER JOIN Table3 ON Table3.Name = Table1.Name
                  AND Table2.Name IS NULL
          WHERE Table2.Name IS NOT NULL OR Table3.Name IS NOT NULL
          ) derived_table
      

      【讨论】:

        【解决方案3】:

        以下内容可以帮助您了解大部分情况。不过,我不确定您是想要每个用户还是整体的聚合。

        另外 - 如果您打算使用 Game3、Game4 等,那么最好的办法是更改您的表格设计,而不是让这个(和其他)查询进一步复杂化。

        SELECT      SUM(U.Score) AS Score,
                SUM(Fouls.Fouls) AS Fouls
        FROM        dbo.Users U
        INNER JOIN  (
            SELECT      COALESCE(G.Name, G2.Name) AS Name,
                    COALESCE(G.Fouls, G2.Fouls) AS Fouls
            FROM        dbo.Game G
            FULL JOIN   dbo.Game2 G2
            ON      G.Name = G2.Name
        ) Fouls
        ON      U.Name = Fouls.Name
        

        【讨论】:

        • 我不想按用户汇总。我正在寻找整体,这会工作吗?复杂性比这更进一步,但我明白你的意思。
        • @Mikael - 试试这个,看看它是否能给你想要的东西。如果聚合不完全正确,将使用 GROUP BY 对其进行排序。
        • 是的,它有效,但现在我需要计算犯规和得分的总值,我将如何应用 GROUP BY 和 COUNT()
        • @Mikael - 你宁愿使用 SUM 并且因为你不想按用户分组,你可以省略 GROUP BY 子句。我已经更新了我的 T-SQL。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多