一尘不染

SQL-SELECT MAX()及其伴随字段

sql

我所拥有的基本上是一个可以用多个表轻松解决的问题,但是我只有一个表可以解决。

考虑以下数据库表

UserID UserName EmailAddress         Source
3K3S9  Ben      ben@myisp.com        user
SF13F  Harry    lharry_x@hotbail.com 3rd_party
SF13F  Harry    reside@domain.com    user
76DSA  Lisa     cake@insider.com     user
OL39F  Nick     stick@whatever.com   3rd_party
8F66S  Stan     myman@lol.com        user

我需要选择所有字段,但只需选择每个用户一次以及他们的电子邮件地址之一(由MAX()函数确定的“最大”地址)。这是我追求的结果…

UserID UserName EmailAddress         Source
3K3S9  Ben      ben@myisp.com        user
SF13F  Harry    lharry_x@hotbail.com 3rd_party
76DSA  Lisa     cake@insider.com     user
OL39F  Nick     stick@whatever.com   3rd_party
8F66S  Stan     myman@lol.com        user

如您所见,“哈利”仅以其“最高”电子邮件地址显示一次,并带有相应的“来源”

当前正在发生的事情是,我们正在对UserID,UserName进行分组,并对EmailAddress和Source使用MAX(),但是这两个字段的最大值并不总是匹配,它们必须来自同一记录。

我通过将表与自身连接在一起尝试了另一个过程,但是我仅设法获得了正确的电子邮件地址,而没有获得该地址的相应“来源”。

任何帮助将不胜感激,因为我已经花了太长时间尝试解决此问题:)


阅读 272

收藏
2021-03-17

共1个答案

一尘不染

如果您使用的是SQL Server 2005或更高版本,

SELECT  UserID, UserName, EmailAddress, Source
FROM    (SELECT UserID, UserName, EmailAddress, Source,
                ROW_NUMBER() OVER (PARTITION BY UserID
                                   ORDER BY EmailAddress DESC) 
                    AS RowNumber
         FROM   MyTable) AS a
WHERE   a.RowNumber = 1

当然,有一些方法可以执行不具有(SQL-Standard)排名功能的相同任务,例如ROW_NUMBERSQL Server自2005年以来才实施-
包括嵌套的依赖查询和带有ON“>”和WHERE ... IS NULL技巧的自我左联接- -但是排名函数使代码易于阅读,并且在理论上可以被SQL
Server Engine很好地优化。

编辑:本文是有关排名的不错的教程,但是它RANK在示例中使用了而不是ROW_NUMBER(或其他排名函数DENSE_RANK)-当根据排序条件在同一分区中的分组行之间存在“联系”时,区别很重要。这篇文章很好地解释了差异。

2021-03-17