我接到的任务是尝试检测具有大量行的表中的一些重复记录。该表包含 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/