sql - 空日期表现

标签 sql oracle performance

我正在查找相同的行,但当出生日期字段为 null 时遇到问题。

我目前有两个脚本能够识别我正在寻找的三种相同性,但我想用一个脚本来实现。

是的,数据可以更新为使用已知日期,这可能意味着空,但我不想更改数据或复制到新表。

我确实设法创建了一个可以完成所有工作的脚本,但运行起来需要花费大量时间。我之所以能做到这一点,全归功于这个answer 。两个脚本的运行时间均不足一秒,而单个脚本则需要 26 分钟。

脚本 1 匹配空出生日期,但缺少相同的名字

SELECT last_name, birthdate, count(distinct first_name) 
FROM merged_person 
    having count(distinct first_name) >1 
GROUP BY last_name, birthdate 
ORDER BY last_name;

脚本 2 遗漏了 null 出生日期

SELECT *
FROM merged_person
WHERE (last_name, birthdate) IN
    (SELECT last_name, birthdate
    FROM merged_person
    GROUP BY last_name, birthdate
    HAVING COUNT(*) > 1
    )
ORDER BY last_name, birthdate;

脚本 3 变体可以找到所有结果,但花费的时间太长。
变体 1

SELECT *
FROM merged_person
WHERE (last_name, nvl(birthdate, '0001-01-01')) IN
    (SELECT last_name, nvl(birthdate, '0001-01-01')
    FROM merged_person
    GROUP BY last_name, birthdate
    HAVING COUNT(*) > 1
    )
ORDER BY last_name, birthdate;

变体2

SELECT *
FROM merged_person
WHERE (last_name, nvl(to_char(birthdate, 'DD-MM-YYYY'), '00-00-0000')) IN
    (SELECT last_name, nvl(to_char(birthdate, 'DD-MM-YYYY'), '00-00-0000')
    FROM merged_person
    GROUP BY last_name, birthdate
    HAVING COUNT(*) > 1
    )
ORDER BY last_name, birthdate;

使用 nvl(birthdate, '0001-01-01') 无法捕获所有情况。

是否有提高性能的方法或其他方法来匹配空出生日期?

编辑:

相同性是具有相同姓氏和出生日期的记录,其余字段对于匹配来说并不重要,但它们是名字,文件编号,员工 ID,性别,一堆雇用信息。

由于我正在处理生产数据,因此无法显示返回的任何行。

示例

  • Bruce Banner,生于 1966 年,Empid 1234,男
  • 莎拉·类纳 (Sarah Banner),生于 1966 年,恩皮德 1345 年,女
  • Anne Rice,空,Empid 1134,女性
  • Ben Rice,Null,Empid 1153,男

识别横幅很容易。是大米造成了问题。

最佳答案

分析函数可以避免自连接和类型转换的问题:

--具有相同姓氏和出生日期的人。 选择名字、姓氏、出生日期 从 (

--All rows, with a count of people with same last name and birth date.
select first_name, last_name, birthdate,
    count(*) over (partition by last_name, birthdate) duplicate_count
from merged_person

) 其中重复计数 >= 2 按名字、姓氏、出生日期排序;


最初的问题是从经典的 NULL 问题开始的:NULL 不等于 NULL,但 NULL 也不等于 NULL。这很令人困惑,并且需要一些时间来理解,但如果您将 NULL 视为“缺少值”,那么它确实有意义。

使用NVL来避免NULL问题是一个好主意,但是隐式类型转换可能会引起问题。使用 ISO 8601 日期文字会更清晰。您已经使用了正确的格式,只需将关键字 DATE 放在其前面即可。

更改:

nvl(birthdate, '0001-01-01')

致:

nvl(birthdate, date '0001-01-01')

关于sql - 空日期表现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56433796/

相关文章:

oracle - ORA-00984: 在具有输入变量的过程中不允许出现列

java - Oracle RDF 表在保存三元组时抛出 ORA-22835 错误

sql - 为什么数据库在更新行时执行删除和插入操作?

javascript - 向箭头函数添加花括号是否可以提高性能?

python - 关于在 Numpy 中向量化 block 操作的建议

javascript - 实例化多个 JavaScript 对象的最佳方式是什么?

mysql - 当尝试更改表时,我收到 "The table ' some table' is full”。为什么?

mysql - 索引提示中的 USE 和 FORCE 有什么区别?

mysql - 获取时间范围 SQL 查询之外的最后一行

mysql 右连接未按预期工作