基于CreatedBy列获取唯一记录且保留双列的SQL查询技术咨询
咱们先拆解下你的需求和当前查询的问题哈:
当前查询的问题
你写的这条SQL:
SELECT DISTINCT nh.InNeoHistoryId, nh.CreatedBy FROM NeoHistory nh GROUP BY nh.CreatedBy, nh.InNeoHistoryId
完全达不到你想要的效果,原因很简单:
InNeoHistoryId是唯一值,每一行的这个字段都不一样。当你把它和CreatedBy一起放在GROUP BY里时,相当于把每一行都当成了独立的分组,最终返回的结果和直接执行SELECT InNeoHistoryId, CreatedBy FROM NeoHistory没有任何区别——所有原始行都会被保留,CreatedBy的重复问题根本没解决。- 这里的
DISTINCT也是多余的,因为GROUP BY已经基于唯一的字段组合做了分组,不会产生重复行。
满足需求的正确实现方式
根据你的需求(保留两列、CreatedBy唯一、不关心InNeoHistoryId具体取值),有两种常用的可行方案:
方案1:用聚合函数取任意ID(最简单直接)
如果你只是需要每个CreatedBy对应一个任意的InNeoHistoryId,用MIN()或MAX()这类聚合函数就可以:
SELECT MIN(nh.InNeoHistoryId) AS InNeoHistoryId, nh.CreatedBy FROM NeoHistory nh GROUP BY nh.CreatedBy
这个查询会为每个唯一的CreatedBy返回最小的InNeoHistoryId(换成MAX()就是最大的),完美满足你“保留两列、CreatedBy唯一”的要求,也能直接给Crystal Reports当输入。
方案2:用窗口函数(适合需要指定行逻辑的场景)
如果后续你想更灵活地选择InNeoHistoryId(比如取每个CreatedBy对应的最新记录ID),可以用窗口函数ROW_NUMBER():
WITH RankedHistory AS ( SELECT nh.InNeoHistoryId, nh.CreatedBy, -- 按CreatedBy分组,每组内按ID降序排名(想取最早的就改成ASC) ROW_NUMBER() OVER (PARTITION BY nh.CreatedBy ORDER BY nh.InNeoHistoryId DESC) AS rn FROM NeoHistory nh ) SELECT InNeoHistoryId, CreatedBy FROM RankedHistory WHERE rn = 1
这个方法会给每个CreatedBy分组里的行排序,然后只取每组的第一行,既保证CreatedBy唯一,又能控制取哪一行的ID。
总结
你的原查询完全不满足需求,改用上面两种方案之一就能达到目的——如果只是要任意ID选方案1,需要指定行逻辑选方案2。
内容的提问来源于stack exchange,提问作者Aleksandar Zoric
相关产品推荐
相关产品推荐

