在一天的特定时刻没有人出现

时间:2017-10-27 04:29:49

标签: sql sql-server tsql

我正在寻找一个查询,其中列出了24小时营业时间中给定时段内出现的人数。这是例如表

Customer_ID    ENTRYDATETIME              EXITDATETIME
-----------------------------------------------------------------    
1001           2017-01-01 09:06:35.477    2017-01-01 12:06:35.477
1001           2017-01-05 11:06:35.477    2017-01-05 17:05:00.000
1002           2017-01-01 14:06:35.477    2017-01-01 19:05:00.000
1003           2017-01-01 14:06:35.477    2017-01-01 20:05:00.000
1067           2017-01-01 14:06:35.477    2017-01-01 16:05:00.000
1067           2017-01-02 14:06:35.477    2017-01-01 15:05:00.000
1067           2017-01-03 14:06:35.477    2017-01-01 16:05:00.000
1091           2017-01-10 14:06:35.477    2017-01-01 18:05:00.000

所以在这里你看到客户1001出现在1stJAN上午9点,上午10点,上午11点,下午12点

同样,客户#1002在1stJAN上午11点,12,13,14,1500出现。

在本月底,我希望看到商店中每小时的平均客户数量。甚至平均每月等等。

有人可以帮我逻辑一下。非常感谢您的时间和精力。

2 个答案:

答案 0 :(得分:2)

你可以使用它。

DECLARE @Temp TABLE (Customer_ID INT, ENTRYDATETIME DATETIME, EXITDATETIME DATETIME)
INSERT INTO @Temp VALUES

(1001,'2017-01-01 09:06:35.477','2017-01-01 12:06:35.477'),
(1001,'2017-01-05 11:06:35.477','2017-01-05 17:05:00.000'),
(1002,'2017-01-01 14:06:35.477','2017-01-01 19:05:00.000'),
(1003,'2017-01-01 14:06:35.477','2017-01-01 20:05:00.000'),
(1067,'2017-01-01 14:06:35.477','2017-01-01 16:05:00.000'),
(1067,'2017-01-02 14:06:35.477','2017-01-02 15:05:00.000'),
(1067,'2017-01-03 14:06:35.477','2017-01-03 16:05:00.000'),
(1091,'2017-01-10 14:06:35.477','2017-01-10 18:05:00.000')

;WITH CTE as
(
    select Customer_ID, CAST(ENTRYDATETIME AS DATE) ENTRYDATE, DATEPART(HOUR, ENTRYDATETIME) ENTRYHOUR from @Temp
    UNION all
    select CTE.Customer_ID, CAST(ENTRYDATETIME AS DATE) DT,  ENTRYHOUR = ENTRYHOUR + 1  from @Temp T INNER JOIN CTE ON T.Customer_ID = CTE.Customer_ID 
        AND ENTRYDATE = CAST(ENTRYDATETIME AS DATE)
        AND (ENTRYHOUR + 1) <= DATEPART(HOUR, EXITDATETIME)
)
SELECT * FROM CTE
order by Customer_ID, ENTRYDATE, ENTRYHOUR

第二种方法:我使用了带时间表的交叉连接,而不是递归CTE。可能比第一种方法工作得更快。

;WITH HourTable AS
(
    SELECT * FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)) Hhr (HourIndex)
)
SELECT 
    T.Customer_ID, 
    CAST(T.ENTRYDATETIME AS DATE) ENTRYDATE, DATEPART(HOUR, DATEADD(HOUR, H.HourIndex, T.ENTRYDATETIME)) ENTRYHOUR 
FROM @Temp T
    INNER JOIN HourTable H ON DATEDIFF( HOUR, T.ENTRYDATETIME, T.EXITDATETIME ) >= H.HourIndex
ORDER BY 
    Customer_ID, 
    ENTRYDATE, 
    ENTRYHOUR

结果:

Customer_ID ENTRYDATE  ENTRYHOUR
----------- ---------- -----------
1001        2017-01-01 9
1001        2017-01-01 10
1001        2017-01-01 11
1001        2017-01-01 12
1001        2017-01-05 11
1001        2017-01-05 12
1001        2017-01-05 13
1001        2017-01-05 14
1001        2017-01-05 15
1001        2017-01-05 16
1001        2017-01-05 17
1002        2017-01-01 14
1002        2017-01-01 15
1002        2017-01-01 16
1002        2017-01-01 17
1002        2017-01-01 18
1002        2017-01-01 19
1003        2017-01-01 14
1003        2017-01-01 15
1003        2017-01-01 16
1003        2017-01-01 17
1003        2017-01-01 18
1003        2017-01-01 19
1003        2017-01-01 20
1067        2017-01-01 14
1067        2017-01-01 15
1067        2017-01-01 16
1067        2017-01-02 14
1067        2017-01-02 15
1067        2017-01-03 14
1067        2017-01-03 15
1067        2017-01-03 16
1091        2017-01-10 14
1091        2017-01-10 15
1091        2017-01-10 16
1091        2017-01-10 17
1091        2017-01-10 18

这就是按小时计算的。

;WITH CTE as
(
    select Customer_ID, CAST(ENTRYDATETIME AS DATE) ENTRYDATE, DATEPART(HOUR, ENTRYDATETIME) ENTRYHOUR from @Temp
    UNION all
    select CTE.Customer_ID, CAST(ENTRYDATETIME AS DATE) DT,  ENTRYHOUR = ENTRYHOUR + 1  from @Temp T INNER JOIN CTE ON T.Customer_ID = CTE.Customer_ID 
        AND ENTRYDATE = CAST(ENTRYDATETIME AS DATE)
        AND (ENTRYHOUR + 1) <= DATEPART(HOUR, EXITDATETIME)
)
SELECT ENTRYHOUR, COUNT(*) AVARAGE FROM CTE
GROUP BY ENTRYHOUR

结果:

ENTRYHOUR   AVARAGE
----------- -----------
9           1
10          1
11          2
12          2
13          1
14          7
15          7
16          6
17          4
18          3
19          2
20          1

答案 1 :(得分:0)

我建议您生成date / time表格(使用CTE或静态表格),然后在&#39; BETWEEN&#39;上加入该表格。 EntryDateTimeExitDateTime