【问题标题】:In a SQL GROUP BY query, what value is used for the non-aggregate columns?在 SQL GROUP BY 查询中,非聚合列使用什么值?
【发布时间】:2011-02-28 15:20:47
【问题描述】:

假设我从 SQL 查询中得到以下数据:

Lastname Firstname Age
Anderson Jane      28
Anderson Lisa      22
Anderson Jack      37

如果我想知道姓安德森的最年长的人的年龄,我可以选择 MAX(Age) 和 GROUP BY Lastname。但我也想知道那个最年长的人的名字。如何确保当 GROUP BY 将 Firstname 值折叠成一行时,我从获得最大年龄的同一行中获取 Firstname 值?

【问题讨论】:

  • 您的“最大年龄”并非来自特定行,因为它是一个集合。想想当你的集合中有另一行 ('Anderson','Bob',37) - max(age) 仍然是 37 但它来自哪一行?

标签: sql


【解决方案1】:

对于那些支持它的 RDBMS(例如,SQL Server 2005+),您可以使用窗口函数:

select t.Lastname, t.Firstname, t.Age
    from (select Lastname, Firstname, Age, 
                 row_number() over (partition by Lastname order by Age desc) as RowNum
              from YourTable
         ) t
    where t.RowNum = 1

对于其他人,您需要一个关于 Lastname 的子查询和一个连接来获取 Firstname:

select yt.Lastname, yt.Firstname, yt.Age
    from YourTable yt
        inner join (select LastName, max(Age) as MaxAge
                        from YourTable
                        group by LastName) q
            on yt.Lastname = q.Lastname
                and yt.Age = q.MaxAge

【讨论】:

  • 值得注意的是,如果给定姓氏的最大年龄在 2 行或更多行之间共享,则您的第一个示例将仅返回一个(不可预测),而您的第二个示例将返回多行
【解决方案2】:

您必须从分组结果中重新连接到表格 - 即创建一个视图或嵌套查询来包含分组依据。

【讨论】:

    【解决方案3】:

    无论您采用何种方法,您需要注意的主要事情是,对于给定的lastname,可能有超过 1 个firstname 具有相同的年龄。

    此查询将仅返回 1 行,但如果您的数据集有多个 37 岁的“安德森”,它可能会返回任何一个:

    select firstname, age
    from yourtable
    where lastname = 'Anderson'
    order by age desc limit 1
    

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 2014-12-27
      • 2020-06-06
      • 1970-01-01
      相关资源
      最近更新 更多