并发调用SQL Server

时间:2018-02-20 23:26:46

标签: sql-server

我写了一个查询来计算并发呼叫的数量(即在任何一分钟内使用了多少电话线)。如果有更快的方式来编写此查询?

    SELECT 
    DATEADD(MINUTE, DATEDIFF(MINUTE, 0, c1.[StartTime]) / 1 * 1, 0) AS [Date_Truncated],
    COUNT(DISTINCT(c2.ID))
FROM records c1
     LEFT JOIN records c2 
       ON DATEADD(minute, DATEDIFF(minute, 0, c1.[StartTime]) / 1 * 1, 0) 
          BETWEEN DATEADD(minute, DATEDIFF(minute, 0, c2.[StartTime]) / 1 * 1, 0) 
                AND DATEADD(minute, DATEDIFF(minute, 0, c2.LeaveTime) / 1 * 1, 0)
GROUP BY 
    DATEADD(minute, DATEDIFF(minute, 0, c1.[StartTime]) / 1 * 1, 0)
ORDER BY 
    [Date_Truncated];

更新

这是一个示例表:

create table records (
StartTime DATETIME default null,
LeaveTime DATETIME  default null,
ID varchar(20));

insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:03:02', '2006-12-30 08:03:04', 'A');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:33:02', '2006-12-30 08:37:45', 'B');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:33:02', '2006-12-30 08:33:05', 'C');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:40:21', '2006-12-30 08:41:25', 'D');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:40:21', '2006-12-30 08:41:25', 'E');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:47:00', '2006-12-30 08:47:47', 'F');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:01', '2006-12-30 08:56:01', 'G');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:01', '2006-12-30 08:56:04', 'H');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:07', '2006-12-30 08:57:37', 'I');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:07', '2006-12-30 08:57:35', 'J');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:28', '2006-12-30 08:56:41', 'K');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:56:28', '2006-12-30 08:56:41', 'L');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:57:08', '2006-12-30 08:57:24', 'M');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:57:09', '2006-12-30 08:57:24', 'N');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:58:02', '2006-12-30 08:58:02', 'O');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:58:59', '2006-12-30 08:59:59', 'R');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 08:58:59', '2006-12-30 08:59:58', 'Q');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 09:00:34', '2006-12-30 09:00:35', 'S');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 09:00:55', '2006-12-30 09:02:55', 'T');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 09:01:27', '2006-12-30 09:01:28', 'U');
insert into records (StartTime, LeaveTime, ID) VALUES ('2006-12-30 09:02:18', '2006-12-30 09:02:18', 'V');

这是输出的样子:

output

1 个答案:

答案 0 :(得分:0)

这应该快一点,虽然扫描记录表可能是瓶颈,如果它是巨大的:

with running_call_count as (
select
    date_truncated = dateadd(minute, datediff(minute, 0, x.calltime), 0),
    concurrent_calls = sum(x.delta) over (order by x.calltime)
    from records r outer apply
        (select starttime, 1 union all select leavetime, -1) x(calltime, delta)
)
select date_truncated, max(concurrent_calls)
from running_call_count
group by date_truncated

..顺便说一句我不认为/ 1 * 1正在做任何事情所以我把它遗漏了。