2017-09-27 19 views
0

我有一個場景(在SQL Server 2012中),我必須確定給定日期的擴展之間的父子關係。我設法將數據轉換成能夠識別主記錄(即,開始呼叫者ID和下一呼叫ID(傳送)),子記錄和結束記錄(即結束呼叫ID)的格式。見下表。找到可重複級別的親子關係

問題是,任何CallID或NextCallID都可以在Master,Sub或End調用當天晚些時候重複使用。我基本上必須找到正確的呼叫組,並且每個組必須重複主呼叫ID。此外,呼叫可以多次傳送,這意味着它可以有很多Sub記錄。

數據:

Timestamp    | CallID  | NextCallID | Type 
------------------------|-------------|-------------|----- 
2017-07-26 14:37:24.000 | 37468024 | 37594497 | M 
2017-07-26 14:51:27.000 | 37594497 | 37595080 | S 
2017-07-26 14:59:30.000 | 37595080 | 37512345 | S 
2017-07-26 14:59:59.000 | 37512345 | NULL  | E 
2017-07-26 18:59:59.000 | 37594497 | NULL  | M 

所需的結果:

Timestamp    | MasterCallID | CallID | NextCallID | Type 
------------------------|------------- |-----------|------------|------- 
2017-07-26 14:37:24.000 | 37468024  | 37468024 | 37594497 | Master 
2017-07-26 14:51:27.000 | 37468024  | 37594497 | 37595080 | Sub/transfer 
2017-07-26 14:59:30.000 | 37468024  | 37595080 | 37512345 | Sub/transfer 
2017-07-26 14:59:59.000 | 37468024  | 37512345 | NULL  | End Call 
2017-07-26 18:59:59.000 | 37594497  | 37594497 | NULL  | Master 

正如你可以從上面的數據集看,呼叫標識37594497是一個孩子到主記錄,然後在當天晚些時候被新記錄/電話的主人。

道歉,如果問題陳述/表格格式不清楚。 在這方面的任何援助將不勝感激。


修訂:

所提出的解決方案不符合以下情形的工作:

數據:

Timestamp    | CallID  | NextCallID | Type 
    ------------------------|-------------|-------------|----- 
    2017-07-26 07:08:32.000 | 37461343 | 37565836 | M 
    2017-07-26 07:31:06.000 | 37565804 | 37565938 | M 
    2017-07-26 07:35:23.000 | 37565836 | 37565909 | S 
    2017-07-26 07:42:23.000 | 37565909 | NULL  | E 
    2017-07-26 07:45:04.000 | 37565938 | 37566044 | S 
    2017-07-26 07:52:59.000 | 37566044 | NULL  | E 
    2017-07-26 18:14:26.000 | 37565461 | 37565909 | M 
    2017-07-26 18:24:48.000 | 37565804 | NULL  | M 
    2017-07-26 18:26:11.000 | 37565836 | NULL  | M 
    2017-07-26 18:29:23.000 | 37565909 | 37566044 | S 
    2017-07-26 18:30:06.000 | 37565938 | NULL  | M 
    2017-07-26 18:33:11.000 | 37566044 | NULL  | E 

輸出(使用CTE查詢):

Timestamp    | MasterCallID| CallID  | NextCallID | Type 
    ------------------------|-------------|-------------|---------------|------- 
    2017-07-26 07:08:32.000 | 37461343 | 37461343 | 37565836  | M 
    2017-07-26 07:31:06.000 | 37565804 | 37565804 | 37565938  | M 
    2017-07-26 07:35:23.000 | 37461343 | 37565836 | 37565909  | S 
    2017-07-26 07:42:23.000 | 37461343 | 37565909 | NULL   | E 
    2017-07-26 07:42:23.000 | 37565461 | 37565909 | NULL   | E 
    2017-07-26 07:45:04.000 | 37565804 | 37565938 | 37566044  | S 
    2017-07-26 07:52:59.000 | 37461343 | 37566044 | NULL   | E 
    2017-07-26 07:52:59.000 | 37565461 | 37566044 | NULL   | E 
    2017-07-26 07:52:59.000 | 37565804 | 37566044 | NULL   | E 
    2017-07-26 18:14:26.000 | 37565461 | 37565461 | 37565909  | M 
    2017-07-26 18:24:48.000 | 37565804 | 37565804 | NULL   | M 
    2017-07-26 18:26:11.000 | 37565836 | 37565836 | NULL   | M 
    2017-07-26 18:29:23.000 | 37461343 | 37565909 | 37566044  | S 
    2017-07-26 18:29:23.000 | 37565461 | 37565909 | 37566044  | S 
    2017-07-26 18:30:06.000 | 37565938 | 37565938 | NULL   | M 
    2017-07-26 18:33:11.000 | 37461343 | 37566044 | NULL   | E 
    2017-07-26 18:33:11.000 | 37565461 | 37566044 | NULL   | E 
    2017-07-26 18:33:11.000 | 37565804 | 37566044 | NULL   | E 

所需的輸出:

Timestamp    | MasterCallID| CallID  | NextCallID | Type 
    ------------------------|-------------|-------------|---------------|------- 
    2017-07-26 07:08:32.000 | 37461343 | 37461343 | 37565836  | M 
    2017-07-26 07:35:23.000 | 37461343 | 37565836 | 37565909  | S 
    2017-07-26 07:42:23.000 | 37461343 | 37565909 | NULL   | E 
    2017-07-26 07:31:06.000 | 37565804 | 37565804 | 37565938  | M 
    2017-07-26 07:45:04.000 | 37565804 | 37565938 | 37566044  | S 
    2017-07-26 07:52:59.000 | 37565804 | 37566044 | NULL   | E 
    2017-07-26 18:14:26.000 | 37565461 | 37565461 | 37565909  | M 
    2017-07-26 18:29:23.000 | 37565461 | 37565909 | 37566044  | S 
    2017-07-26 18:33:11.000 | 37565461 | 37566044 | NULL   | E 
    2017-07-26 18:26:11.000 | 37565836 | 37565836 | NULL   | M 

將非常感謝您的幫助。

問候

+0

這不是「建議的解決方案不適用於以下情況」。您更改了原始方案。所以,我認爲如果它對應於您的原始查詢,您應該投票回答。然後,我們可以嘗試幫助您解決這一新問題。 – etsa

+0

請閱讀S.O的介紹。並學習格式化文本。然後在你的「新」問題中添加一個簡短的描述,並顯示你的努力(在這種情況下,你試圖做什麼來解決你的新請求從查詢開始回答?) – etsa

+0

我正在處理它,但它不是很容易(至少現在看起來如此......) – etsa

回答

0

更好的閱讀你的要求,我認爲你必須使用遞歸查詢(CTE)。在遞歸部分中,它提取所有層次結構。我跟蹤最後一列(M2)中的主呼叫。

這個查詢不是基於調用的時間順序作爲我以前的答案。它僅使用CallID和NextCallID,因此您可以在同一時間使用呼叫層次結構。

;WITH A AS (SELECT Timestamp,CallID,NextCallID,Type, CallID AS MasterCallID 
      FROM CALLS WHERE TYPE='M' 
      UNION ALL 
      SELECT B.Timestamp,B.CallID,B.NextCallID,B.Type, A.MasterCallID 
      FROM CALLS B 
      INNER JOIN A ON A.NEXTCALLID=B.CALLID 
      WHERE B.TYPE<>'M') 
SELECT Timestamp 
     , MasterCallID 
     , CallID 
     , NextCallID 
     , CASE Type WHEN 'M' Then 'Master' WHEN 'S' THEN 'Sub/Transfer' WHEN 'E' THEN 'End Call' ELSE '' END AS Type 
FROM A 
ORDER BY TIMESTAMP 

輸出:

新版本之後
+-------------------------+------------+----------+------------+--------------+ 
|  Timestamp  | MASTERCALL | CallID | NextCallID |  Type  | 
+-------------------------+------------+----------+------------+--------------+ 
| 2017-07-26 14:37:24.000 | 37468024 | 37468024 | 37594497 | Master  | 
| 2017-07-26 14:51:27.000 | 37468024 | 37594497 | 37595080 | Sub/Transfer | 
| 2017-07-26 14:59:30.000 | 37468024 | 37595080 | 37512345 | Sub/Transfer | 
| 2017-07-26 14:59:59.000 | 37468024 | 37512345 | NULL  | End Call  | 
| 2017-07-26 18:59:59.000 | 37594497 | 37594497 | NULL  | Master  | 
+-------------------------+------------+----------+------------+--------------+ 

問題編輯(上面的查詢可以創建錯誤的 「鏈接」 呼叫mastercall):

; WITH A AS (SELECT Timestamp,CallID,NextCallID,Type, CallID AS MasterCallID, Timestamp AS TIMEMASTER 
      FROM CALLS WHERE TYPE='M' 
      UNION ALL 
      SELECT B.Timestamp,B.CallID,B.NextCallID,B.Type, A.MasterCallID, A.TIMEMASTER 
      FROM CALLS B 
      INNER JOIN A ON B.CALLID=A.NEXTCALLID AND B.TIMESTAMP>A.TIMESTAMP   
      WHERE B.TYPE<>'M') 
SELECT A.Timestamp 
     , A.MasterCallID 
     , A.CallID 
     , A.NextCallID 
     , CASE A.Type WHEN 'M' Then 'Master' WHEN 'S' THEN 'Sub/Transfer' WHEN 'E' THEN 'End Call' ELSE '' END AS Type 
FROM A 
INNER JOIN (SELECT TIMESTAMP, CALLID, MAX(TIMEMASTER) MAXTIMEM FROM A GROUP BY TIMESTAMP, CALLID) C ON A.TIMESTAMP=C.TIMESTAMP AND A.CALLID=C.CALLID AND A.TIMEMASTER = C.MAXTIMEM 
ORDER BY TIMEMASTER, TIMESTAMP 
; 

輸出新的樣本數據:

Timestamp    MasterCallID CallID  NextCallID Type 
------------------------ ------------- ------------- ------------- ------------ 
2017-07-26 07:08:32.000 37461343  37461343  37565836  Master 
2017-07-26 07:35:23.000 37461343  37565836  37565909  Sub/Transfer 
2017-07-26 07:42:23.000 37461343  37565909  NULL   End Call 
2017-07-26 07:31:06.000 37565804  37565804  37565938  Master 
2017-07-26 07:45:04.000 37565804  37565938  37566044  Sub/Transfer 
2017-07-26 07:52:59.000 37565804  37566044  NULL   End Call 
2017-07-26 18:14:26.000 37565461  37565461  37565909  Master 
2017-07-26 18:29:23.000 37565461  37565909  37566044  Sub/Transfer 
2017-07-26 18:33:11.000 37565461  37566044  NULL   End Call 
2017-07-26 18:24:48.000 37565804  37565804  NULL   Master 
2017-07-26 18:26:11.000 37565836  37565836  NULL   Master 
2017-07-26 18:30:06.000 37565938  37565938  NULL   Master 
+0

謝謝etsa,我會給它一個更多的排列,並讓你知道它是否有效。 – solidawe

+0

@Wazimh幾分鐘後我會發布另一個查詢。我認爲後者將最適合您的要求。 – etsa

+0

@Wazimh看到我更新的答案。 – etsa

0

可以使用SUMOVER嘗試grouping在初始查詢的元素:

DECLARE @DataSource TABLE 
(
    [Timestamp] DATETIME2 
    ,[CallID] BIGINT 
    ,[NextCallID] BIGINT 
    ,[Type] CHAR(1) 
); 

INSERT INTO @DataSource ([Timestamp], [CallID], [NextCallID], [Type]) 
VALUES ('2017-07-26 14:37:24.000', 37468024, 37594497, 'M') 
     ,('2017-07-26 14:51:27.000', 37594497, 37595080, 'S') 
     ,('2017-07-26 14:59:30.000', 37595080, 37512345, 'S') 
     ,('2017-07-26 14:59:59.000', 37512345, NULL, 'E') 
     ,('2017-07-26 18:59:59.000', 37594497, NULL, 'M'); 

SELECT * 
     ,SUM(IIF([Type] = 'M', 1, 0)) OVER (ORDER BY [Timestamp] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Group] 
FROM @DataSource 
ORDER BY [Timestamp] ASC; 

enter image description here

知道該組的每個呼叫,我們只需要找到CallID,其中TypeM每個組:

WITH DataSource AS 
(
    SELECT * 
      ,SUM(IIF([Type] = 'M', 1, 0)) OVER (ORDER BY [Timestamp] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Group] 
    FROM @DataSource 
) 
SELECT * 
     ,MAX(IIF([Type] = 'M', [CallID], NULL)) OVER (PARTITION BY [Group]) 
FROM DataSource 
ORDER BY [Timestamp] ASC; 

enter image description here

+0

感謝gotqn,您的解決方案也適用於此提供的數據集。我唯一擔心的是隻有在生產中使用更大的數據集時才按timeStamp進行分組。將對此進行測試並提供反饋。 – solidawe

+0

您的查詢停止了一些場景。請參閱上面對我的問題的修正。欣賞它。 – solidawe