oracle 使用SQL从下表中查找未接来电并回拨

huus2vyu  于 2023-05-22  发布在  Oracle
关注(0)|答案(2)|浏览(147)

我有一个无法解决的问题,谁能给我一些建议?

From            To      Start    End
9901234567  8854320145  10:00   10:00
9435678911  7657894335  10:30   10:33
8764091245  9765487678  09:45   09:47
8854320145  9901234567  10:05   10:07
7609123987  8854320145  11:13   11:13
6501928465  7609123987  08:09   08:13

这里from是一个电话号码to也是一个电话号码,开始和结束是通话的持续时间。根据这些详细信息,我需要识别未接来电和回拨。我应该如何使用SQL解决这个问题?

hrysbysz

hrysbysz1#

在Oracle 12中,您可以将MATCH_RECOGNIZELEASTGREATEST一起使用:

SELECT "From", "To", "Start", "End"
FROM   (
  SELECT t.*,
         LEAST("From", "To") AS lst,
         GREATEST("From", "To") AS gst
  FROM   table_name t
)
MATCH_RECOGNIZE(
  PARTITION BY lst, gst
  ORDER BY "Start", "End"
  ALL ROWS PER MATCH
  PATTERN ( missed_call callback )
  DEFINE
    missed_call AS  "Start" = "End",
    callback    AS  PREV("From") = "To"
                AND PREV("To") = "From"
                AND "Start" < "End"
);

其中,对于样本数据:

CREATE TABLE table_name ("From", "To", "Start", "End") AS
SELECT '9901234567', '8854320145',  '10:00', '10:00' FROM DUAL UNION ALL
SELECT '9435678911', '7657894335',  '10:30', '10:33' FROM DUAL UNION ALL
SELECT '8764091245', '9765487678',  '09:45', '09:47' FROM DUAL UNION ALL
SELECT '8854320145', '9901234567',  '10:05', '10:07' FROM DUAL UNION ALL
SELECT '7609123987', '8854320145',  '11:13', '11:13' FROM DUAL UNION ALL
SELECT '6501928465', '7609123987',  '08:09', '08:13' FROM DUAL UNION ALL
SELECT '1234567890', '1234567890',  '09:00', '09:01' FROM DUAL UNION ALL
SELECT '1234567890', '1234567890',  '09:05', '09:06' FROM DUAL UNION ALL
SELECT '1111111111', '2222222222',  '10:00', '10:01' FROM DUAL UNION ALL
SELECT '2222222222', '1111111111',  '10:05', '10:06' FROM DUAL;

输出:
| 从|到|开始|结束|
| --------------|--------------|--------------|--------------|
| 9901234567| 8854320145|十点整|十点整|
| 8854320145| 9901234567|十点零五分|十点零七分|
fiddle

cyej8jka

cyej8jka2#

我相信你可以将表连接到它本身,将from链接到to,反之亦然:

SELECT mc.*, cb.*
FROM yourtable mc --MissedCalls
    INNER JOIN yourtable cb --Callbacks
        ON mc.To = cb.From 
        AND mc.From = cb.To
        AND cb.Start > cb.End --A cb/callback happens after a missed call
WHERE mc.Start = mc.end --An mc/MissedCall has the same start and end time

如果存在多个未接呼叫和相同的从/到/从的回叫,则此操作将失败。目前尚不清楚这是否存在于您的数据中。
为了解决这个问题,创建一个新的派生表,将两个号码之间的呼叫从1到N编号,而不管它们的顺序(x呼叫y或y呼叫x),这允许我们确定双方之间的下一个呼叫是否是回叫。

WITH call_relationships AS 
(
    --Create a call number for each number-to-number relationship
    SELECT dt.*, 
        row_number() OVER (PARTITION BY From, To ORDER BY Start) as call_number, 
        CASE WHEN Start = End THEN 'mc' as missed_call_indicator
    FROM 
        (
            SELECT From as num1, To as num2, Start, End, CAST('To' AS VARCHAR(4)) as rel FROM yourtable
            UNION ALL
            SELECT To, From, Start, End, 'From' FROM yourtable
        ) dt
)
SELECT mc.num1 as missed_call_from, 
    mc.num2 as missed_call_to, 
    mc.Start as missed_call_time,
    cb.Start as call_back_start_time,
    cb.End as call_back_end_time
FROM call_relationships mc 
    INNER JOIN call_relationships cb 
        ON cb.rel = 'To' --Select only calls where y calls x
        AND mc.num1 = cb.num1
        AND mc.num2 = cb.num2
        AND mc.call_number + 1 = cb.call_number -- only consider the very next call between these two numbers
WHERE mc.missed_call_indicator IS NOT NULL
    and mc.rel = 'From' --Select only calls where x calls y

相关问题