Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.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_Duplicates - Fatal编程技术网

SQL删除基于其他行的重复行

SQL删除基于其他行的重复行,sql,oracle,duplicates,Sql,Oracle,Duplicates,我有两个表,一个表显示发送给客户的所有程序的记录,另一个表显示用户对其采取操作的所有程序的记录。我的最终目标是计算发送给用户的程序中有多少被执行。我现在有办法,但有个问题。程序可能会多次发送给用户,我将在一天内以20为例。如果用户在24小时内对该程序采取行动,我不希望将其计算为19个未采取行动的程序和1个已采取行动的程序。我希望它算作1对0失败的程序执行操作 需要筛选包含发送给客户的程序的表格,以便发送给客户的每个程序每24小时仅显示一次 我的解决方案是有一个窗口类型的东西,这样一旦一个程序被发

我有两个表,一个表显示发送给客户的所有程序的记录,另一个表显示用户对其采取操作的所有程序的记录。我的最终目标是计算发送给用户的程序中有多少被执行。我现在有办法,但有个问题。程序可能会多次发送给用户,我将在一天内以20为例。如果用户在24小时内对该程序采取行动,我不希望将其计算为19个未采取行动的程序和1个已采取行动的程序。我希望它算作1对0失败的程序执行操作

需要筛选包含发送给客户的程序的表格,以便发送给客户的每个程序每24小时仅显示一次

我的解决方案是有一个窗口类型的东西,这样一旦一个程序被发送给客户,它就会被该客户“锁定”24小时,这样它就不会多次出现在我的“发送给客户的程序”查询中

我有一张这样的桌子:

Customer    Time    Program
-----------------------------------
1           8:05    a
1           10:30   a
1           11:30   a
1           12:30   b
1           1:25    a
2           9:38    b
2           10:38   c
2           1:36    c
2           2:40    c
2           3:41    b
.
.
.
我想得到一个表查询,而不是删除,在一定的时间范围内删除每个客户重复的程序!我知道

以下是我想要的3hr时间框架,例如:

Customer    Time    Program
-----------------------------------
1           8:05    a
1           11:30   a
1           12:30   b
2           9:38    b
2           10:38   c
2           2:40    c
2           3:41    b
.
.
.
试试这个:

select *
from t
where not exists (select 1 from t t2
                  where t2.customer = t.customer and
                        t2.program = t.program and
                        t2.time - t.time < 3.0/24 and
                        t2.time > t.time
                 )

日期-时间算法依赖于数据库,但这对许多数据库都有效。

我认为您的意思只能通过递归查询来解决。以下是一个解决方案:

WITH cte AS
  ( SELECT 
        customer, program, time,
        ROW_NUMBER() 
            OVER (PARTITION BY customer, program
                  ORDER BY time)
          AS rn, 
        MIN(time) 
            OVER (PARTITION BY customer, program
                  ORDER BY time 
                  RANGE BETWEEN 3.0/24 FOLLOWING 
                            AND UNBOUNDED FOLLOWING)
          AS next_time
    FROM a
  )

SELECT 
    customer, time, program
FROM 
    cte
START WITH rn = 1
CONNECT BY PRIOR customer = customer
       AND PRIOR program = program
       AND PRIOR next_time = time
ORDER BY 
    customer, time, program ;
您也可以用上面的FIRST_VALUEtime替换MINtime,并获得相同的结果。这可能更有效

测试时间

大桌子上的效率可能不会很好。您可以尝试使用较小的数据集运行查询

您至少应该添加此索引,以便它进行索引扫描:

CREATE INDEX ix                -- choose a name for the index
  ON tableX                    -- the table name
  (customer, program, time) ;
您也可以跳过最终排序,或将其更改为与使用的索引更相似:

ORDER BY 
    customer, program, time ;

您使用的是什么RDBMS?Time datetime、timestamp等是什么类型的列???您使用的rdbms和版本是什么?时间的数据类型是什么?对于任何代码来说,识别1:36在10:38之后都是非常困难的。SQL developer如果没有答案解决了您的问题,请在此处澄清,不要发布新的相同问题。很抱歉,如果这与您得到的其他建议相冲突,但新问题意味着您有一个新问题,至少与已解决的现有问题略有不同。这是正确的方向,但不会显示所需的结果。@ypercube。我想你指的是问题的同一部分。我只是把它加进去了。除此之外,这不是OP想要的。我认为,滚动窗口要求只能通过递归查询来解决。@ypercube。我不是这样理解这个问题的。期望输出中a的第二行支持我对问题的理解。我将把它标记为正确答案,因为它非常接近我想要的。只有递归函数才能实现的“移动窗口”是不会发生的,因为我运行了一个小时的递归函数,不耐烦了,所以我放弃了。谢谢你@ypercube gordon