Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在列中查找连续值_Sql_Oracle - Fatal编程技术网

Sql 如何在列中查找连续值

Sql 如何在列中查找连续值,sql,oracle,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 现在我们有了一张桌子。重复记

我被赋予这个任务,试图在一个有大量行的表中检测一些重复记录。该表由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
现在我们有了一张桌子。重复记录具有唯一的事件编号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 |
这是一个重复记录的例子。存在连续的事件编号id,其余所有列具有相同的信息。我们相信我们的系统已经创建了重复的事件一段时间了,但现在这种情况不应该发生,所以我想查询整个联接表,并找到任何包含数据完全相同但事件编号不同且连续的行的内容

到目前为止,我成功地进行了一个简单的查询,显示了所有具有相同信息的行,不包括event\u number\u 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    |

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

总体思路:将具有相同值的行分组,按任期编号id、工作开始日期、工作结束日期、金额、,使用分析函数min和row\u number从零开始查找每个组的最小事件编号\u id和组内事件编号\u id的行号,然后将最小id和行号之和与事件编号\u id进行比较。对于连续的数字,它们必须相等:

with t as (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)
select *
  from (select t.*, 
               min(event_number_id) over (partition by tenure_number_id, work_start_date, work_end_date, amount) + 
               row_number() over (partition by tenure_number_id, work_start_date, work_end_date, amount order by event_number_id) - 1 group_id
          from t)
 where event_number_id = group_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;
效率将取决于几个因素,例如扫描基表的效率和数据集的大小

比较这种方法和分析功能方法的执行计划会很有趣。这种基于通用表表达式的连接应该非常有效,因为它依赖于哈希连接,只要它们留在内存中,几乎没有成本,这是一个很大的问号


如果事件编号id不是连续的,我倾向于使用分析函数——例如,如果可能存在间隙,这将更难作为连接实现。考虑到其中一个表是递增的,我认为值得在一个联接上下赌注。

您显示的是对两个表的引用,而不是对一个表的引用。两个表中是否都有重复项?正如我所说,这是一个连接表。第一个表包含一些信息,但第二个表中的保留期\编号\ id列包含在内非常关键。问题是,我们每个任期都有重复的活动。我们采用的方法是找出连续事件是否具有相同的保留期编号、开始日期、结束日期和金额。没关系,您可以在一个查询中连接两个表,以投影所需的列,将其包装,并有效地将其视为您正在查询的表。我想有两种方法:1。找到重复的,然后检查它们是否有连续的数字,或2。查找连续的数字,然后确定它们是否重复。您可以从t开始作为原始查询选择*从…Dmitry开始,非常有趣!感谢您在入睡时如此专注于解决此问题:
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;