根据子句的最小日期

tp5buhyn  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(420)

我需要帮助做以下工作。我有下表的通信:
通讯ID通讯时间通讯状态6369/3/2021 8:48:49新63610/3/2021 10:47:31接受63612/3/2021 8:41:42新63612/3/2021 9:43:49接受
第二个答复表(来文):
通信ID响应时间响应状态63610/3/2021 9:30:49显示63611/3/2021 7:48:49实现63612/3/2021 10:28:49显示63617/3/2021 11:19:49实现
我需要根据通信id对通信进行分组,但我还需要知道最近的“实现时间”,即在当前通信时间之后第一次实现响应的时间。
因此,我需要这样的东西:
通信idmax(通信时间)实现响应时间63610/3/2021 10:47:3111/3/2021 7:48:4963612/3/2021 9:43:4917/3/2021 11:19:49
你能帮我个忙吗?我应该使用什么样的分析功能(或其他步骤)?沟通的状态可以改变,但我只考虑“实现”React的时间。可以有更多的实际React,但我只需要“最接近的一个”的时间沟通。每个“已实现”响应应该在结果集中有单独的“行”,它应该“划分”通信。
非常感谢你

eh57zj3b

eh57zj3b1#

从oracle 12c,您可以 UNION ALL 连接两个表,然后使用 MATCH_RECOGNIZE :

SELECT *
FROM   (
  SELECT 'c' AS type, id, time, status FROM communications
UNION ALL
  SELECT 'r' AS type, id, time, status FROM responses
)
MATCH_RECOGNIZE(
  PARTITION BY id
  ORDER     BY time
  MEASURES
    new_comms.time AS new_time,
    realized.time AS realized_time
  ONE ROW PER MATCH
  PATTERN ( new_comms other_comms* realized )
  DEFINE
    new_comms AS (type, status) IN (('c', 'new')),
    other_comms AS (type, status) NOT IN (('c', 'new'),('r', 'realized')),
    realized AS (type, status) IN (('r', 'realized'))
)

注意:这将不允许重叠通信。
或者,在早期版本中,您可以使用 LEAD 用一个 CASE 表达式:

SELECT id,
       time AS new_time,
       realized_time
FROM   (
  SELECT t.*,
         LEAD(
           CASE WHEN type = 'r' AND status = 'realized' THEN time END
         ) IGNORE NULLS OVER (
           PARTITION BY id
           ORDER BY time
         ) AS realized_time
  FROM   (
    SELECT 'c' AS type, id, time, status FROM communications
  UNION ALL
    SELECT 'r' AS type, id, time, status FROM responses
  ) t
)
WHERE  type = 'c'
AND    status = 'new'

注意:这将允许重叠通信(但两个 new 行可能会匹配相同的 realized 行)。
对于样本数据:

CREATE TABLE communications ( ID, TIME, STATUS ) AS
SELECT 636, DATE '2021-03-09' + INTERVAL '08:48:49' HOUR TO SECOND, 'new' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-10' + INTERVAL '10:47:31' HOUR TO SECOND, 'accepted' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-12' + INTERVAL '08:41:42' HOUR TO SECOND, 'new' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-12' + INTERVAL '09:43:49' HOUR TO SECOND, 'accepted' FROM DUAL;

CREATE TABLE responses( ID, TIME, STATUS ) AS
SELECT 636, DATE '2021-03-10' + INTERVAL '09:30:49' HOUR TO SECOND, 'displayed' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-11' + INTERVAL '07:48:49' HOUR TO SECOND, 'realized' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-12' + INTERVAL '10:28:49' HOUR TO SECOND, 'displayed' FROM DUAL UNION ALL
SELECT 636, DATE '2021-03-17' + INTERVAL '11:19:49' HOUR TO SECOND, 'realized' FROM DUAL;

输出:
idnew\u time63021-03-09 08:48:492021-03-11 07:48:4963021-03-12 08:41:422021-03-17 11:19:49
db<>在这里摆弄

h43kikqp

h43kikqp2#

似乎您只需要每个已实现响应的最大通信时间。单向:

select
  r.communication_id,
  r.response_time,
  max(c.communication_time)
from responses r
join communications c
  on c.communication_id = r.communication_id
  and c.communication_time < r.response_time 
where r.response_status = 'realized'
group by r.communication_id, r.response_time
order by r.communication_id, r.response_time;

另一个:

select
  r.communication_id,
  r.response_time,
  last_c.communication_time
from responses r
cross apply
(
  select communication_time
  from communications c
  where c.communication_id = r.communication_id
  and c.communication_time < r.response_time 
  order by c.communication_time desc
  fetch first row only
) last_c
where r.response_status = 'realized'
order by r.communication_id, r.response_time;

相关问题