如何按一列的最大值获取SQL行,按另一列分组

Posted

技术标签:

【中文标题】如何按一列的最大值获取SQL行,按另一列分组【英文标题】:How to get SQL row by max of one column, group by another column 【发布时间】: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 实际上安全吗?

【问题讨论】:

【参考方案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 首先拥有相关版本,然后添加了另外两个。 然而,在撰写本文时,它们都不足以接受:(

以上是关于如何按一列的最大值获取SQL行,按另一列分组的主要内容,如果未能解决你的问题,请参考以下文章

我需要连接三个表,将结果按一列分组,并显示另一列的最大值

按一列分组并在熊猫中找到另一列的总和和最大值

SQL group by:选择另一列有其最小值/最大值的值

Mysql,如何使用另一列的最大值对一组行进行分组?

将一列的多个结果行连接成一个,按另一列分组[重复]

如何按一列分组并对另一列的值进行排序?