为每个不同的列值选择第一行 [重复]
Posted
技术标签:
【中文标题】为每个不同的列值选择第一行 [重复]【英文标题】:Select first row for each different column value [duplicate] 【发布时间】:2017-07-24 00:09:42 【问题描述】:有一个像这样的表T:
ID DateTime asha
AF35 15-01-17 af
AF35 14-01-17 la
AF35 13-01-17 fi
DF57 15-01-17 sk
DF57 14-01-17 sj
DG36 15-01-17 be
DG36 14-01-17 dh
什么是最简单的mysql
查询,只返回每个唯一ID
的第一行,按最近的DateTime
排序?
我的预期结果是这样的:
ID DateTime asha
AF35 15-01-17 af
DF57 15-01-17 sk
DG36 15-01-17 be
我尝试了SELECT * FROM T GROUP BY ID ORDER BY DateTime
,但是,mysql 返回一个错误,因为没有将其他列添加到子句中。如果我添加它们,我仍然会得到重复的 ID 结果。
【问题讨论】:
即来自欺骗:select * from (select * from t order by DateTime desc) group by ID
,但您必须将sql-mode
设置为不包含ONLY_FULL_GROUP_BY
,这样才能正常工作。
虽然受到广泛好评,但恐怕链接页面上接受的答案依赖于未记录的黑客攻击。也就是说,还有其他答案已记录。
【参考方案1】:
我最喜欢编写此查询的方法是使用 not exists 子句:
select *
from T as t1
where not exists (
select 1
from T as t2
where t2.ID = t1.ID
and t2.DateTime > t1.DateTime
)
【讨论】:
干得好,我之前错过了不同的 asha。 谢谢! @SqlZim,意味着很多来自大师:) 我不明白这是怎么回事。select 1 from T as t2
不会简单地返回一个名为 1 的列,每行都有一堆 1 吗?如果 t2 没有名为 ID 的列,where 子句如何与 t2.ID 一起使用?
@mtsfaria,我能看出你的困惑 :) 我去过一次。表 t2 确实有 ID 列。它只是 T 表的别名。我在这里所做的是在 ID 列上将 T 表与自身连接起来,如果有任何行 t2 具有较晚的 DateTime,它将被排除,因为整个事情都在 NOT EXISTS 子句中,只留下 t1 中的行其中 DateTime 是最新的。如您所见,select 1
要么返回 1,要么不返回。您不妨使用 select "blah"
而不是 1,您会得到相同的结果。
谢谢阿南德!我了解这项技术并成功地将其应用于我的需求。【参考方案2】:
SELECT Distinct(ID),DateTime,asha FROM T GROUP BY ID ORDER BY DateTime desc
使用上述查询来获得唯一的 Id 记录。
【讨论】:
DISTINCT 不是函数。此查询返回不确定的结果。不好。以上是关于为每个不同的列值选择第一行 [重复]的主要内容,如果未能解决你的问题,请参考以下文章