我已经得到了这张表格,其中包含了我们呼叫中心代理商在各州所花费的时间。 以下是其中一条记录的示例:
AgentName, AgentState, BeginTransitionTime, EndTransitionTime, BeginHour, EndHour
Breana Rascon(994840), Work Time, 3/14/16 7:56:19 AM, 3/14/16 11:02:51 AM, 7, 11
我希望以上记录最终分成5条记录,如下:
Breana Rascon(994840), Work Time, 3/14/16 7:56:19 AM, 3/14/2016 7:59:59 AM, 7, 7
Breana Rascon(994840), Work Time, 3/14/16 8:00:00 AM, 3/14/2016 8:59:59 AM, 8, 8
Breana Rascon(994840), Work Time, 3/14/16 9:00:00 AM, 3/14/2016 9:59:59 AM, 9, 9
Breana Rascon(994840), Work Time, 3/14/16 10:00:00 AM, 3/14/2016 10:59:59 AM, 10, 10
Breana Rascon(994840), Work Time, 3/14/16 11:00:00 AM, 3/14/16 11:02:51 AM, 11, 11
我开始使用光标,当记录被分割超过2小时时工作得很好,但不止于此而且代码开始失控。任何帮助都将受到高度赞赏。
谢谢!
答案 0 :(得分:0)
如果你使用数字表,那么这是一个简单的连接和一些转换。否则你需要一个CTE或其他一些窗口函数。
numberz表
DECLARE @UpperLimit INT = 1000000;
IF OBJECT_ID('dbo.numberz','U') IS NULL
BEGIN
CREATE TABLE dbo.numberz (numVal INT);
WITH n(rn) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
)
INSERT dbo.numberz
SELECT [numVAl] = 0
UNION ALL
SELECT rn
FROM n
WHERE rn <= @UpperLimit;
CREATE UNIQUE CLUSTERED INDEX uix_numVal ON dbo.numberz([numVAl]);
END
表格创建
CREATE TABLE tbl_agentTime
(
AgentName NVARCHAR(255)
, AgentState NVARCHAR(255)
, BeginTransitionTime DATETIME
, EndTransitionTime DATETIME
, BeginHour INT
, EndHour INT
)
INSERT tbl_agentTime
VALUES ('BREANA RASCON(994840)', 'WORK TIME', '2016-03-14 7:56:19', '2016-03-14 11:02:51', 7, 11)
记录拆分
select
AgentName
, AgentState
, BeginTransitionTime = CASE WHEN numVal = BeginHour then BeginTransitionTime else cast(cast(BeginTransitionTime as date) as nvarchar(10)) +' '+cast(numVal as nvarchar(2))+':00:00' end
, EndTransitionTime = CASE WHEN numVal = EndHour then EndTransitionTime else cast(cast(ENDTRANSITIONTIME as date) as nvarchar(10)) +' '+cast(numVal as nvarchar(2))+':59:59' end
, BeginHour = numVal
, EndHour = numVal
from tbl_agentTime a
join numberz n on n.numVal >= a.BeginHour and n.numVal<= a.EndHour
答案 1 :(得分:0)
如果你想使用递归CTE,它看起来像这样......
WITH cte
AS (SELECT [AgentName],
[AgentState],
[BeginTransitionTime],
[EndTransitionTime],
[NewEndTransitionTime] = DATEADD(second,-1,DATEADD(hour,DATEDIFF(hour,0,[BeginTransitionTime]) + 1,0)),
[BeginHour],
[EndHour] = [BeginHour]
FROM agents
UNION ALL
SELECT [AgentName],
[AgentState],
DATEADD(hour,DATEDIFF(hour,0,[NewEndTransitionTime]) + 1,0),
[EndTransitionTime],
[NewEndTransitionTime] = CASE WHEN [EndTransitionTime] < [NewEndTransitionTime] THEN [EndTransitionTime]
ELSE DATEADD(second,-1,DATEADD(hour,DATEDIFF(hour,0,[NewEndTransitionTime]) + 2,0))
END,
[BeginHour] + 1,
[EndHour] + 1
FROM cte
WHERE DATEADD(hour,DATEDIFF(hour,0,[NewEndTransitionTime]) + 1,0) < [EndTransitionTime]
)
SELECT [AgentName],
[AgentState],
[BeginTransitionTime],
[EndTransitionTime] = CASE WHEN [EndTransitionTime] < [NewEndTransitionTime] THEN [EndTransitionTime] ELSE [NewEndTransitionTime] END,
[BeginHour],
[EndHour]
FROM cte
这也可以使用数字表来完成。虽然只有少量记录,但速度较慢,但对于较大的数据集,速度可能会更快。
WITH E1(N)
AS (SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 1
),
E2([Hour])
AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL
)) Num
FROM E1 a,
E1 b
)
SELECT [AgentName],
[AgentState],
[BeginTransitionTime] = CASE WHEN a.BeginHour = E2.[Hour]
THEN [BeginTransitionTime]
ELSE DATEADD(hour,DATEDIFF(hour,0,[BeginTransitionTime]) + (E2.[Hour] - a.BeginHour),0)
END,
[EndTransitionTime] = CASE WHEN [EndTransitionTime] < DATEADD(second, -1 , DATEADD(hour,DATEDIFF(hour,0,[BeginTransitionTime]) + (E2.[Hour] - a.BeginHour + 1),0))
THEN [EndTransitionTime]
ELSE DATEADD(second, -1 , DATEADD(hour,DATEDIFF(hour,0,[BeginTransitionTime]) + (E2.[Hour] - a.BeginHour + 1),0))
END,
[BeginHour] = E2.[Hour],
[EndHour] = E2.[Hour]
FROM agents a
JOIN E2 ON E2.[Hour] BETWEEN a.BeginHour AND a.EndHour