sql - 如何查找列中的连续值

标签 sql oracle

我接到的任务是尝试检测具有大量行的表中的一些重复记录。该表包含 2 个连接表。首先我有:

select 
b.event_number_id, b.tenure_number_id, a.work_start_date, a.work_stop_date, a.amount
from
MTA.mta_sow_event a, mta_tenure_event_xref b
where
a.event_number_id = b.event_number_id

现在我们有一个可以工作的表了。重复的记录具有唯一的 event_number_id,重命名字段将包含相同的数据,因此如下所示:

| event_number_id |  tenure_number_id | work_start_date | work_stop_date |amount|
|-----------------|-------------------|-----------------|----------------|------|
|  5532733        | 688203            |     01-SEP-14   |  25-SEP-14     | 5000 |
|  5532734        | 688203            |     01-SEP-14   |  25-SEP-14     | 5000 |

因此,这是重复记录的示例。有连续的 event_number_id,并且所有剩余列都具有相同的信息。我们相信我们的系统已经创建重复事件一段时间了(这不应该发生),所以我想查询整个连接表并找到任何具有完全相同数据但不同且连续的行的内容事件编号。

到目前为止,我成功地进行了一个简单的查询,该查询显示了具有相同信息的所有行(不包括 event_number_id 列):

select 
b.tenure_number_id, a.work_start_date, a.work_stop_date, a.amount, count(*)
from
MTA.mta_sow_event a, mta_tenure_event_xref b
where
a.event_number_id = b.event_number_id
group by
b.tenure_number_id, a.work_start_date, a.work_stop_date, a.amount
having
count(*) > 1

返回:

|  tenure_number_id | work_start_date | work_stop_date |amount|Count(*)|
|-------------------|-----------------|----------------|------|--------|
| 688203            |     01-SEP-14   |  25-SEP-14     | 5000 |   2    |

问题是,有时有些行具有相同的数据,但可能是有效的,因此我们此时能做的最好的事情就是找到具有连续 event_number_id 的任何匹配行。这就是我挂断的地方。有没有办法只提取包含这些连续数字的行?

最佳答案

这是一种基于数据集联接的方法:

with cte_base_data as (
  select 
     ... your query here ...)
select 
from cte_base_data t1 join
     cte_base_data t2 on (t1.tenure_number_id = t2.tenure_number_id and
                          t1.work_start_date  = t2.work_start_date  and
                          t1.work_stop_date   = t2.work_stop_date   and
                          t1.amount           = t2.amount)
where t1.event_number_id = t2.event_number_id - 1;

效率取决于几个因素,例如扫描基表的效率和数据集的大小。

比较此方法和分析功能方法的执行计划将会很有趣。这种基于公共(public)表表达式的联接应该非常高效,因为它依赖于哈希联接,只要它们保留在内存中,就几乎没有成本(对此有一个很大的问号)。

如果 event_number_id 不连续,例如,如果可能存在间隙,那么我会倾向于使用分析函数,这将更难实现为连接。鉴于其中一个是另一个递增的,我认为值得在连接上押注。

关于sql - 如何查找列中的连续值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29571932/

相关文章:

sql - LINQ区分大小写

SQL - 如何更改计算列上的列

mysql - 使用 CONTAINS 进行 SQL 全文搜索会引发几何错误

oracle - 如何检查引用游标是否从 pl/sql 过程返回数据

java - NUMBER 的精度和小数位数是否会影响 ResultSet.getObject() 的行为

sql - 按照LINK中的代码后PL/SQL MENU疑惑

c# - 基于表的一个字段在 Linq 中区分

ruby-on-rails - 更新表单在多对多关系中根本不起作用

sql - 在Oracle中使用和不使用KEEP进行分区

sql - 如何防止 dbms_output.put_line 修剪前导空格?