我有两个表(一个显示发送给客户的所有程序的记录,另一个显示用户采取操作的所有程序的记录)。我的最终目标是计算发送给用户的那些程序中有多少人被采取行动。我现在有办法做到这一点,但有一个问题。可以在一天内将程序多次发送给用户(我将使用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
.
.
.
我想获得一个表(查询,而不是删除),在一定时间内删除每个客户的重复程序(令人困惑!我知道)
这是我想要的(例如3小时时间框架):
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
.
.
.
答案 0 :(得分:2)
试试这个:
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
)
日期时间算术取决于数据库,但这适用于其中许多数据库。
答案 1 :(得分:1)
我认为您的意思可以通过递归查询(仅)解决。这是一个解决方案:
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 ;
您也可以将MIN(time)
替换为FIRST_VALUE(time)
以上,并获得相同的结果。它可能更有效率。
大桌上的效率可能不会很好。您可以尝试使用较小的数据集运行查询。
你应该至少添加这个索引,所以它会进行索引扫描:
CREATE INDEX ix -- choose a name for the index
ON tableX -- the table name
(customer, program, time) ;
您也可以跳过最终排序或更改它,使其更类似于使用的索引:
ORDER BY
customer, program, time ;