我有一个场景(在SQL Server 2012中),我必须确定给定日期之间的扩展之间的父子关系。我设法将数据转换成可以识别主记录(即Start CallerID和nextCallerID(transfer)),子记录和结束记录(即结束CallID)的格式。见下表。
问题是任何CallID或NextCallID都可以在Master,Sub或End调用的同一天重复。我基本上必须找到正确的呼叫组,并且每组必须重复Master CallID。此外,呼叫可以多次传输,这意味着它可以有许多子记录。
数据:
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
从上面的数据集中可以看出,CallID 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 :(得分: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 |
+-------------------------+------------+----------+------------+--------------+
问题编辑后的新版本(上述查询可能会创建错误的&#34;链接&#34; call-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
答案 1 :(得分:0)
您可以使用grouping
SUM
来尝试OVER
初始查询中的元素:
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;
了解每次通话的小组,我们只需找到CallID
,其中每个小组的Type
为M
:
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;