【问题标题】:How to get SQL row by max of one column, group by another column如何按一列的最大值获取SQL行,按另一列分组
【发布时间】:2012-02-14 05:12:51
【问题描述】:

我需要从旧数据库中读取用户以用于新系统中的统计信息,但我没有原始用户表。但是有一个统计表,其中包含每年的总和,我也可以在其中找到所有需要的用户信息。此外,这也只给我活跃的用户,这是我需要的。

该表有以下相关列:(此处不相关统计列)

  • 用户 ID
  • 名字
  • 姓氏
  • 电子邮件
  • 年份

我希望 UserID 是不同的,因此它是我可以在 GROUP BY 中拥有的唯一列。 我将在 Year 上运行 MAX,以获取最近一年的值。 FirstName、LastName 和 Email 需要与 MAX(Year) 所在的行相同。换句话说,这些年来人们可能同时更改了姓名和电子邮件,我只想要最后一个,因为它是唯一相关的。

我对 SQL 查询的最佳建议如下:

SELECT UserID, Firstname, LastName, Email, MAX(Year) AS Year
FROM myTable
GROUP BY UserID
ORDER BY LastName, FirstName

唯一的问题是 SQL Server 2008 不允许我这样做,因为所有列要么必须使用 MAX 之类的函数,要么是 GROUP BY 的一部分。 FirstName、LastName 和 Email 列不能在 GROUP BY 下,因为这样会产生太多记录。似乎以某种方式将 MAX 放在所有这些上,但是我无法知道 MAX 函数实际在哪个列上工作。我不确定这是否会出现问题,但我没有时间查看 100 000 行来查看是否真的存在问题。

简而言之,我想要一整行的五列,其中 MAX 仅适用于一列,而 GROUP BY 则适用于另一列。有没有人有好的解决方案,或者在所有非分组行上使用 MAX 实际上安全吗?

【问题讨论】:

    标签: sql sql-server-2008 group-by max greatest-n-per-group


    【解决方案1】:

    几个答案...


    相关子查询...

    SELECT
      *
    FROM
      myTable
    WHERE
      Year = (SELECT MAX(Year) FROM myTable AS lookup WHERE lookup.UserID = myTable.UserID)
    


    加入派生聚合...

    SELECT
      *
    FROM
      myTable
    INNER JOIN
      (SELECT UserID, MAX(Year) AS Year FROM myTable GROUP BY UserID) AS lookup
        ON  lookup.UserID = myTable.UserID
        AND lookup.Year   = myTable.Year
    


    使用 ROW_NUMBER() 排序 CTE...

    WITH
      sequenced_data AS
    (
      SELECT
        ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY Year DESC) AS sequence_id,
        *
      FROM
        myTable
    )
    SELECT
      *
    FROM
      sequenced_data
    WHERE
      sequence_id = 1
    

    【讨论】:

    • 第二个查询的子查询中需要GROUP BY UserID
    • @ypercube - 哎呀 :) 该死的电话让我分心了 :)
    • 哇,这反应很快。谢谢大家的回答!我马上就要下班回家,但晚上会在家里仔细观察它们。
    • 谢谢!现在尝试一下,它的工作原理,使用你们两个给出的例子。我以前知道 JOIN,但距离我上次尝试它们已经有五年多了,所以它显然已经全部消失了。很高兴你让我重回正轨。 :)
    【解决方案2】:

    您每个用户只有一年的记录吗?如果是,那么您可以使用 old'n'good join:

    SELECT m.UserID, m.Firstname, m.LastName, m.Email, m.Year
    FROM myTable m
        INNER JOIN (
            SELECT UserID, MAX(Year) as Year
            FROM myTable
            GROUP BY UserID
        ) x ON x.UserID=m.UserID and x.Year=m.Year
    ORDER BY m.LastName, m.FirstName
    

    当然,您可以使用来自较新 SQL 版本的构造,我只是已经习惯了较旧(=更通用)的可能性:)。

    【讨论】:

    • 我不明白为什么这个答案比 Dems 的好。他的回答包含这个,并且是第一个回答的。
    • @FlorinGhita - Avro 会在我完成打字之前开始打字。我不会因为提交答案而抨击 Avro :) 而且,嗯,我的错字 ypercube 必须指出 blush
    • Arvo 首先发布了此查询。 Dems 首先拥有相关版本,然后添加了另外两个。
    • 然而,在撰写本文时,它们都不足以接受:(
    猜你喜欢
    • 2019-10-17
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2018-07-13
    • 2013-06-28
    • 2023-02-07
    相关资源
    最近更新 更多