如何按一列的最大值获取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行,按另一列分组的主要内容,如果未能解决你的问题,请参考以下文章