簡體   English   中英

查找未接來電30分鍾內客戶服務部門完成的回電話數

[英]Find the number of return calls that were done by customer care within 30 minutes of the missed call

考慮接收客戶呼叫的客戶服務中心,Starttime和Endtime表示會話開始時間和結束時間。 未接來電是沒有發生對話的電話。 對於任何未接來電,客戶服務部門都會回復電話。

對於下面給出的表,

CREATE TABLE CustomerCare (fromnumber INT, tonumber INT, starttime DATETIME,endtime DATETIME)

INSERT INTO CustomerCare (fromnumber,tonumber,starttime,endtime) 
VALUES
(100,1800,'2019-08-13 18:40:00','2019-08-13 18:40:00'),
(1800,100,'2019-08-13 18:55:00','2019-08-13 18:57:00'),
(200,1800,'2019-08-13 19:30:00','2019-08-13 19:30:00'),
(1800,200,'2019-08-13 20:05:00','2019-08-13 20:10:00'),
(300,1800,'2019-08-13 21:00:00','2019-08-13 21:00:00'),
(1800,300,'2019-08-13 21:20:00','2019-08-13 21:25:00'),
(400,1800,'2019-08-13 07:00:00','2019-08-13 07:00:00'),
(500,1800,'2019-08-13 8:00:00','2019-08-13 8:05:00')

在此輸入圖像描述

查找未接來電30分鍾內客戶服務部門完成的回電話數。

第四行表示一個這樣的回叫。

任何人都可以幫助SQL查詢。

首先你找到未接來電,然后你會發現客戶服務的回電。 你發現時間不同了

select  *
from    CustomerCare mc
        cross apply -- get call back time
        (   
            select  top 1 *
            from    CustomerCare x
            where   x.fromnumber    = mc.tonumber
            and     x.tonumber  = mc.fromnumber
            and     x.starttime > mc.starttime
            order by x.starttime
        ) cb
where   mc.starttime = mc.endtime  -- missed call
and     datediff(minute, mc.starttime, cb.starttime) > 30 -- time different between 
                                                          -- missed call and callback

@Squirrel打敗了我,我的答案原來的答案基本上與他相同,但我會發布我放在一起的內容,因為它也說明為什么APPLY如此優秀。

首先,為了獲得最佳性能,您需要在啟動時使用聚簇索引(或覆蓋索引)。 例如

CREATE CLUSTERED INDEX CL_CustomerCare_starttime ON dbo.CustomerCare(starttime);

接下來,這是你如何使用JOIN(因為你提到它)來做到這一點:

SELECT 
  cc.fromnumber,
  cc.tonumber, 
  missedcalltime = CAST(CAST(cc.starttime AS TIME) AS CHAR(5)),
  callbacktime   = CAST(CAST(x.starttime AS TIME) AS CHAR(5)),
  timetocallback = datediff(minute, cc.starttime, x.starttime)
FROM   dbo.CustomerCare AS cc
JOIN   dbo.CustomerCare AS x
  ON   cc.tonumber = x.fromnumber
 AND   x.tonumber  = cc.fromnumber
 AND   cc.starttime < x.starttime
WHERE datediff(minute, cc.starttime, x.starttime) <= 30;

現在,APPLY版本(這是我在看到松鼠回答之前放在一起的):

SELECT 
  cc.fromnumber,
  cc.tonumber, 
  missedcalltime = CAST(CAST(cc.starttime AS TIME) AS CHAR(5)),
  callbacktime   = CAST(CAST(x.starttime AS TIME) AS CHAR(5)),
  timetocallback = cb.t
FROM   dbo.CustomerCare AS cc
CROSS APPLY 
(
  SELECT TOP (1) x.starttime
  FROM     dbo.CustomerCare AS x
  WHERE    cc.tonumber = x.fromnumber
  AND      x.tonumber  = cc.fromnumber
  AND      cc.starttime < x.starttime
  ORDER BY x.starttime
) AS x
CROSS APPLY (VALUES(datediff(minute, cc.starttime, x.starttime))) AS cb(t)
WHERE       cb.t <= @callback;

兩者都歸來:

fromnumber  tonumber    missedcalltime callbacktime timetocallback
----------- ----------- -------------- ------------ --------------
100         1800        18:40          18:55        15
300         1800        21:00          21:20        20

關於APPLY的第一個很酷的事情是如何使用它來為值設置別名以使我的代碼“DRYer”。 (DRY =不要重復自己)。 由於表達式為datediff(minute, cc.starttime, x.starttime)多次使用,我可以使用APPLY處理表達式,然后多次引用它作為cb.t. 注意這一行:

CROSS APPLY (VALUES(datediff(minute, cc.starttime, x.starttime))) AS cb(t)

這是APPLY如何使代碼更清晰,更容易調試的示例。

關於APPLY強大功能的第二個也許更重要的例子是如何使用子查詢加入外部查詢。 我上面的兩個例子並不完全相同。 從理論上講,如果在30分鍾內有多個“回叫”,JOIN版本將返回它們。 由於這可能是一個邊緣情況,在半小時內要求“TOP(1)”返回呼叫就足夠了,並且性能會更好。 如果檢查兩個查詢的執行計划 - 當連接到CustomerCare時,連接版本會讀取更多行(28),APPLY版本將讀取22行。 如果在APPLY版本中將TOP(1)更改為TOP([任何大於1]),它將讀取28行。 同樣,這是另一種可以使用APPLY來調整性能的方法。

最后,關於子查詢中TOP的重要注釋...如果在APPLY子查詢中刪除ORDER BY,則當存在正確索引列的ORDER BY時,子查詢將讀取58行而不是22行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM