为每个不同的列值选择第一行 [重复]

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 不是函数。此查询返回不确定的结果。不好。

以上是关于为每个不同的列值选择第一行 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

选择不同的和非不同的列值

根据第三列值在 bigquery 中选择两个不同的列

仅基于一个不同的列获取数据表的所有列值[重复]

Laravel/VueJs。如何根据传入的列值显示不同颜色的按钮?

根据haversine距离公式选择不同的列值?

如何检查来自不同数据框的列值?