存在重复项时如何选择唯一记录

Posted

技术标签:

【中文标题】存在重复项时如何选择唯一记录【英文标题】:How to select unique records when duplicates exist 【发布时间】:2021-09-27 11:36:18 【问题描述】:

我正在尝试编写一个查询,只显示每个 APEL_ID 的最新 HEAR_DT

SELECT APEL_ID, HEAR_DT 
FROM HEARINGS
APEL_ID HEAR_DT
101 01-OCT-08
101 02-OCT-08
101 03-OCT-08
102 06-OCT-08
102 07-OCT-08
102 08-OCT-08
103 09-OCT-08
103 10-OCT-08
103 11-OCT-08
104 23-OCT-08
104 24-OCT-08
104 25-OCT-08
104 25-OCT-08

当我像往常一样编写查询时,我在一定程度上获得了唯一记录,但是 HEAR_DT 相同的记录都显示出来了

HEAR_DT 是“日期”而不是“日期时间”数据类型,所以我无法使用时间 选择最大值的组件

是否可以对此查询(或编写的不同查询)执行任何操作,以仅显示唯一记录。我想显示任何显示为重复项的内容。他们中的哪一个被选中并不重要。 (类似于“Top 1”或“Any”)

SELECT APEL_ID, MAX(HEAR_DT) AS LATEST_HEAR_DT 
FROM HEARINGS 
GROUP BY APEL_ID
APEL_ID LATEST_HEAR_DT
101 03-OCT-08
102 08-OCT-08
103 11-OCT-08
104 25-OCT-08
104 25-OCT-08

【问题讨论】:

这不应该发生 - 假设您没有发生任何奇怪的事情,例如 APEL_ID 被设置为 '104 ',末尾有一个空格(假设它是一个字符串,不是数字)。 按照你的说法,看起来好像 APEL_ID 不同,而不是 HEAR_DT。因为,MAX 将选择它的最大值,但是 - 按 APEL_ID 分组 - 正是该列产生了差异。它的(APEL_ID)数据类型是什么?你确定它是真的 104吗? Oracle没有纯日期数据类型,因为Oracle的日期实际上是一个日期时间。 dump(APEL_ID, 16) 添加到选择列表中,看看两者 104 有什么区别。对于字符串,它会以十六进制为您打印一个代码点 这样你绝对必须创建一个minimal reproducible example,因为你声称使用多年的东西实际上不起作用。在极简的路上,你一定会自己找到答案 【参考方案1】:

这个查询:

SELECT APEL_ID, MAX(HEAR_DT) AS LATEST_HEAR_DT 
FROM HEARINGS 
GROUP BY APEL_ID;

每个APEL_ID 应该只返回一行。它不会返回多行。

如果您想要原始数据中的行,每个 APEL_ID 一行,请使用窗口函数:

SELECT h.*
FROM (SELECT h.*,
             ROW_NUMBER() OVER (PARTITION BY APEL_ID ORDER BY HEAR_DT DESC) as seqnum
      FROM HEARINGS h
     ) h
WHERE seqnum = 1;

【讨论】:

【参考方案2】:

这里是解决方案。这行得通

SELECT UNIQUE APEL_ID, MAX(TO_DATE(HEAR_DT, 'DD-MON-YY')) AS LATEST_HEAR_DT 
FROM mytable  
GROUP BY APEL_ID

【讨论】:

以上是关于存在重复项时如何选择唯一记录的主要内容,如果未能解决你的问题,请参考以下文章

如何从表 A 中选择表 B 中不存在的记录 [重复]

如何在 DolphinDB 表的列中选择唯一元素?

MySQL 从具有重复引用条目的联合表中选择唯一记录

excel使用记录(转)

连接sql表以选择连接表中不存在的记录[重复]

如何解决Oracle“不能创建唯一索引,发现重复记录”问题