我所拥有的基本上是一个可以通过多个表轻松解决的问题,但我只有一个表来完成它。
考虑以下数据库表
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
正如你所看到的,“Harry”只用他的“最高”电子邮件地址显示一次相应的“来源”
目前正在发生的事情是我们正在对UserID,UserName进行分组,并使用MAX()作为EmailAddress和Source,但这两个字段的最大值并不总是匹配,它们需要来自同一记录。
我已经通过自己加入表来尝试了另一个过程,但我只是设法获得了正确的电子邮件地址,但没有获得该地址的相应“来源”。
任何帮助都会受到赞赏,因为我已经花了太长时间试图解决这个问题:)
答案 0 :(得分:8)
如果您使用的是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_NUMBER
,SQL Server自2005年以来只实现了这一功能 - 包括嵌套的依赖查询和带有{的自左连接{1}}包括'>'和ON
技巧 - 但排名函数使得SQL Server引擎可以很好地优化可读的代码(<理论上)。
修改:this article是一个很好的排名教程,但它在示例中使用WHERE ... IS NULL
而不是RANK
(或其他排名函数,ROW_NUMBER
) - 当根据排序标准在同一分区中的分组行之间存在“联系”时,区别很重要。 this post很好地解释了差异。
答案 1 :(得分:5)
select distinct * from table t1
where EmailAddress =
(select max(EmailAddress) from table t2
where t1.userId = t2.userId)
答案 2 :(得分:0)
select distinct
*
from
SomeTable a
inner join (
select max(emailAddress), userId
from
SomeTable
group by
userId
) b on a.emailAddress = b.emailAddress and a.userId = b.userId
答案 3 :(得分:0)
我认为我的解决方案与已经提出的解决方案不同:
select * from foo where id = ( select id from foo F where F.bar = foo.bar order by F.baz limit 1 )
这为您提供了具有最大baz的所有foo记录,与具有相同bar的其他foo记录相比。