SQL Server:按小时计算办公室中的客户端数

时间:2016-01-20 21:28:58

标签: sql-server

我正在使用SQL 2012,尝试使用到达时间和出发时间(00:01-01:00,01:01-02:00等)计算办公室中的客户数量)。我希望在它的到达时间开始计算客户,每小时一直到它的出发时间。 例如:

CREATE TABLE #Clients(

GUID NUMERIC(16,0),
ArrivalTime DATETIME NOT NULL,
DepartTime DATETIME NOT NULL)

GO

INSERT INTO #Clients (GUID, ArrivalTime, DepartTime)
SELECT '9158300270', '2016-01-17 00:02:00.000', '2016-01-17 01:39:32.407' 
UNION ALL
SELECT '9158400270', '2016-01-17 00:05:00.000', '2016-01-17 02:55:09.920' 
UNION ALL
SELECT '9158600270', '2016-01-17 00:14:00.000', '2016-01-17 03:25:14.860' 
UNION ALL
SELECT '9158700270', '2016-01-17 00:44:00.000', '2016-01-17 03:37:51.700' 
UNION ALL
SELECT '9158800270', '2016-01-17 01:58:00.000', '2016-01-17 02:35:14.883' 
UNION ALL
SELECT '9158900270', '2016-01-17 02:04:00.000', '2016-01-17 03:26:20.353' 
UNION ALL
SELECT '9159100270', '2016-01-17 02:44:00.000', '2016-01-17 4:57:00.157'

我希望得到的结果显示如下:

00-01 | 01-02 | 02-03 | 03-04 | 04-05
4       5       6       4       1

感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

SELECT  [0], [1], [2], [3], [4]
FROM
    (
        SELECT
            h.DayHour,
            COUNT(c.ArrivalTime) People
        FROM
        (
            SELECT 0 AS DayHour
            UNION ALL
            SELECT 1
            UNION ALL
            SELECT 2
            UNION ALL
            SELECT 3
            UNION ALL
            SELECT 4
        ) h
        LEFT OUTER JOIN #Clients c ON 
            CAST(c.ArrivalTime AS TIME) <= CAST(CAST(h.DayHour + 1 AS VARCHAR(MAX)) + ':00' AS TIME) AND
            CAST(c.DepartTime AS TIME) > CAST(CAST(h.DayHour AS VARCHAR(MAX)) + ':00' AS TIME)
        GROUP BY
            h.DayHour
    ) c
PIVOT (MIN(People) FOR DayHour IN ([0], [1], [2], [3], [4])) p;

答案 1 :(得分:1)

; WITH a AS ( SELECT *, CONVERT(VARCHAR(5), arrivaltime, 108)atime, CONVERT(VARCHAR(5), departtime, 108) dtime 
             FROM #clients )
SELECT count( CASE WHEN atime <= '01:00' THEN 1 END) AS '00-01', count( CASE WHEN atime <= '02:00' AND dtime>='01:00' THEN 1 END) AS '01-02', 
       count( CASE WHEN atime <='03:00' AND dtime>='02:00' THEN 1 END) AS '02-03', count( CASE WHEN atime <= '04:00' AND dtime >='03:00' THEN 1 END) AS '03-04', 
       count( CASE WHEN atime <='05:00' AND dtime>='04:00' THEN 1 END) AS '04-05' 
       FROM a

答案 2 :(得分:0)

这感觉有点沉重,就像它可以被优化,变得更优雅或简洁,但它确实返回了正确的结果。我发现最具挑战性的是每小时时段的范围是动态的,这就是使用循环的原因。我觉得这是一个更好的解决方案,但它正在回避我。

CREATE TABLE #Clients(

GUID NUMERIC(16,0),
ArrivalTime DATETIME NOT NULL,
DepartTime DATETIME NOT NULL)

GO

INSERT INTO #Clients (GUID, ArrivalTime, DepartTime)
SELECT '9158300270', '2016-01-17 00:02:00.000', '2016-01-17 01:39:32.407' 
UNION ALL
SELECT '9158400270', '2016-01-17 00:05:00.000', '2016-01-17 02:55:09.920' 
UNION ALL
SELECT '9158600270', '2016-01-17 00:14:00.000', '2016-01-17 03:25:14.860' 
UNION ALL
SELECT '9158700270', '2016-01-17 00:44:00.000', '2016-01-17 03:37:51.700' 
UNION ALL
SELECT '9158800270', '2016-01-17 01:58:00.000', '2016-01-17 02:35:14.883' 
UNION ALL
SELECT '9158900270', '2016-01-17 02:04:00.000', '2016-01-17 03:26:20.353' 
UNION ALL
SELECT '9159100270', '2016-01-17 02:44:00.000', '2016-01-17 4:57:00.157'


DECLARE @MinArrive datetime = (SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, MIN(ArrivalTime)), 0) FROM #Clients);
DECLARE @MaxDepart datetime = (SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, MAX(DepartTime)) + 1, 0) FROM #Clients);

CREATE TABLE #Results
    (
    StartTime datetime,
    EndTime datetime
    );

DECLARE @i datetime = @MinArrive;

WHILE @i < @MaxDepart
BEGIN
    INSERT INTO #Results
        (
        StartTime,
        EndTime
        )
    VALUES
        (
        @i,
        DATEADD(HOUR, 1, @i)
        );

    SET @i = DATEADD(HOUR, 1, @i);
END

SELECT
    r.StartTime,
    r.EndTime,
    COUNT(c.GUID) PeopleInOffice
FROM
    #Results r
    LEFT JOIN
    #Clients c
    ON
        c.ArrivalTime < r.EndTime
        AND
        c.DepartTime > r.StartTime
GROUP BY
    r.StartTime,
    r.EndTime;

DROP TABLE #Results;
DROP TABLE #Clients;

答案 3 :(得分:0)

Shriop真的帮助了我,并给了我这个想法。但是我想我会发布最终为我工作的东西。

CREATE TABLE #Clients(

GUID NUMERIC(16,0),
ArrivalTime DATETIME NOT NULL,
DepartTime DATETIME NOT NULL)

GO

INSERT INTO #Clients (GUID, ArrivalTime, DepartTime)
SELECT '9158300270', '2016-01-17 00:02:00.000', '2016-01-17 01:39:32.407' 
UNION ALL
SELECT '9158400270', '2016-01-17 00:05:00.000', '2016-01-17 02:55:09.920' 
UNION ALL
SELECT '9158600270', '2016-01-17 00:14:00.000', '2016-01-17 03:25:14.860' 
UNION ALL
SELECT '9158700270', '2016-01-17 00:44:00.000', '2016-01-17 03:37:51.700' 
UNION ALL
SELECT '9158800270', '2016-01-17 01:58:00.000', '2016-01-17 02:35:14.883' 
UNION ALL
SELECT '9158900270', '2016-01-17 02:04:00.000', '2016-01-17 03:26:20.353' 
UNION ALL
SELECT '9159100270', '2016-01-17 02:44:00.000', '2016-01-17 4:57:00.157'

SELECT COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '01:00:00.000' THEN '1'    END) AS '0-1'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '02:00:00.000' AND CAST(DepartTime AS TIME) > '01:00:00.000' THEN '1' END) AS '1-2'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '03:00:00.000' AND CAST(DepartTime AS TIME) > '02:00:00.000' THEN '1' END) AS '2-3'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '04:00:00.000' AND CAST(DepartTime AS TIME) > '03:00:00.000' THEN '1' END) AS '3-4'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '05:00:00.000' AND CAST(DepartTime AS TIME) > '04:00:00.000' THEN '1' END) AS '4-5'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '06:00:00.000' AND CAST(DepartTime AS TIME) > '05:00:00.000' THEN '1' END) AS '5-6'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '07:00:00.000' AND CAST(DepartTime AS TIME) > '06:00:00.000' THEN '1' END) AS '6-7'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '08:00:00.000' AND CAST(DepartTime AS TIME) > '07:00:00.000' THEN '1' END) AS '7-8'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '09:00:00.000' AND CAST(DepartTime AS TIME) > '08:00:00.000' THEN '1' END) AS '8-9'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '10:00:00.000' AND CAST(DepartTime AS TIME) > '09:00:00.000' THEN '1' END) AS '9-10'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '11:00:00.000' AND CAST(DepartTime AS TIME) > '10:00:00.000' THEN '1' END) AS '10-11'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '12:00:00.000' AND CAST(DepartTime AS TIME) > '11:00:00.000' THEN '1' END) AS '11-12'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '13:00:00.000' AND CAST(DepartTime AS TIME) > '12:00:00.000' THEN '1' END) AS '12-13'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '14:00:00.000' AND CAST(DepartTime AS TIME) > '13:00:00.000' THEN '1' END) AS '13-14'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '15:00:00.000' AND CAST(DepartTime AS TIME) > '14:00:00.000' THEN '1' END) AS '14-15'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '16:00:00.000' AND CAST(DepartTime AS TIME) > '15:00:00.000' THEN '1' END) AS '15-16'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '17:00:00.000' AND CAST(DepartTime AS TIME) > '16:00:00.000' THEN '1' END) AS '16-17'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '18:00:00.000' AND CAST(DepartTime AS TIME) > '17:00:00.000' THEN '1' END) AS '17-18'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '19:00:00.000' AND CAST(DepartTime AS TIME) > '18:00:00.000' THEN '1' END) AS '18-19'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '20:00:00.000' AND CAST(DepartTime AS TIME) > '19:00:00.000' THEN '1' END) AS '19-20'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '21:00:00.000' AND CAST(DepartTime AS TIME) > '20:00:00.000' THEN '1' END) AS '20-21'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '22:00:00.000' AND CAST(DepartTime AS TIME) > '21:00:00.000' THEN '1' END) AS '21-22'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '23:00:00.000' AND CAST(DepartTime AS TIME) > '22:00:00.000' THEN '1' END) AS '22-23'
,COUNT(CASE WHEN CAST(ArrivalTime AS TIME) < '23:59:58.999' AND CAST(DepartTime AS TIME) > '23:00:00.000' THEN '1' END) AS '23-24'
FROM #Clients

DROP TABLE #Clients