2017-10-01 3 views
1

단일 DATETIME 필드가 주어지면 몇 가지 솔루션이 시간별로 그룹화 된 것으로 나타났습니다. 필자의 경우 DATETIME 범위를 사용하여 결과를 시간별로 그룹화하고 개수를 구해야합니다.주어진 시간 범위에 대해 시간 단위로 그룹화

아래 테이블 구조를 설명하려고합니다. 내 데이터 표는 다음과 같습니다.

mysql> select * from access_logger; 
+---------+---------------------+---------------------+ 
| user_id | entered_at   | exit_at    | 
+---------+---------------------+---------------------+ 
| 20178 | 2017-09-11 07:02:35 | 2017-09-11 10:10:09 | 
| 18998 | 2017-09-11 08:02:35 | 2017-09-11 08:41:45 | 
| 6754 | 2017-09-11 08:02:35 | 2017-09-11 12:06:42 | 
| 18998 | 2017-09-11 09:02:35 | 2017-09-11 13:30:43 | 
| // results continues....       | 
+---------+---------------------+---------------------+ 

위의 테이블 구조를 기반으로 나는 매 시간마다 얼마나 많은 사용자가 시스템에 연결되었는지보고 싶습니다. 예상 결과는 다음과 같습니다.

각 시간에 대한 결과를 독립적으로 가져 오는 쿼리를 만들었습니다.

mysql> select "10" as hours, count(user_id) as count 
    -> from access_logger 
    -> where hour(entered_at) <=10 and hour(exit_at) >= 10; 

+------+-------+ 
|hours | count | 
+------+-------+ 
| 10 |  3 | 
+------+-------- 

위의 쿼리는 단 한 시간 그룹에 대한 출력을 얻습니다. 24 개의 행에 24 시간 동안 출력을 생성하는 쿼리를 작성하려면 어떻게해야합니까?

+0

테스트되지 않는 이유는 무엇입니까? – Ravi

+0

기본적으로 결과에 날짜가 필요 없으며 사용자가 지정된 시간 내에 있는지 확인해야합니다. – BlueBird

+0

mysql이 – zarruq

답변

1

은 테이블을 제공 (또는 당신의 다른 테이블)은 쿼리를 결합 할 수 있고

SELECT @N := @N +1 AS hour 
FROM access_logger , (SELECT @N:=-1) dum LIMIT 23; 

SQL SELECT to get the first N positive integers

즉에서 발견 24 개 이상의 행이

select a.hour, count(b.user_id) as count 
from access_logger b inner join (SELECT @N := @N +1 AS hour 
     FROM access_logger , (SELECT @N:=-1) dum LIMIT 23) a on 
hour(entered_at) <= a.hour and hour(exit_at) >= a.hour; 

죄송합니다, 손에는 MySQL은 없어, 그래서 이것은 그래서, 당신이 날짜 포함되지 않습니다

+0

이 쿼리는 훌륭하게 작동합니다. 소금을 더 넣으면 돼. 'a.hour를 선택하고 ezc_device_history에서 카운트 (b.mac) b 내부 조인 (SELECT @N : = @N +1 AS 시간 from ezc_device_history, (SELECT @N : = - 1) dum LIMIT 24) a on hour (entered_at) <= a.hour 및 hour (exit_at)> = a.hour에 의한 a.hour 그룹; – BlueBird

0

당신은

당신은 start_timeend_time

사이에 각 시간 동안 총 사용자 수를 계산하는 저장 프로 시저를 만들 수 HOUR

SELECT HOUR(entered_at) AS Hours, COUNT(user_id) AS Total_Users  
FROM access_logger 
GROUP BY HOUR(entered_at); 

편집 ==로 그룹을 사용할 필요가

begin p1 INT; SET p1=1; counter LOOP select @p1 as Hours, count(*) as total_user from access_logger where @p1 between hour(start) and hour(end) ; SET p1 = p1 + 1; IF p1=24 THEN LEAVE counter; END IF; END LOOP counter; end; 
+0

을 지원하면 [temportal database] (https://en.wikipedia.org/wiki/Temporal_database)를 탐색 할 수 있습니다. 이것은 좋은 해결책입니다. 단일 datetime 필드가 있고 사용자 로그인이 떨어지는 지 확인할 필요가있는 경우 주어진 시간에. 내 경우에는 사용자의 기간이 주어진 시간에 속하는지 확인해야합니다. 10:00에 입력하고 12:00에 종료하는 사용자는이 쿼리에 따라 시간 (11)으로 떨어지지 않습니다. – BlueBird

+0

@BlueBird 나는 당신을 얻지 못했습니다. 이 요구 사항을 설명과 함께 게시 할 수 있습니까? – Ravi

+0

만약 당신이 내 질문에 위. 샘플 레코드와 예상 결과를 제공했습니다. 그것은 모두를 설명합니다. 예를 들어 오전 10시에 입장하고 저녁 2시 30 분에 퇴장한다고 가정 해 보겠습니다. 그래서 당신은 모든 시간 (10, 11, 12, 13, 14) 시간에 빠지게 될 것입니다.나 한테 말 했니? – BlueBird

0

이것은 미친 엔지니어링 대답입니다. 시간을 사용하십시오. ary 테이블과 UNION ALL 쿼리. 이것은 확실히 수백만 행에 대해서는 작동하지 않습니다. 임시 테이블은 SQL 세션 기간 동안 작동합니다. 응용 프로그램 서버가 연결 풀을 사용하는 경우 쿼리 후 삭제할 수 있습니다.

DROP TEMPORARY TABLE IF EXISTS aTemp; 
CREATE TEMPORARY TABLE aTemp ENGINE=memory AS 
(Select hour(entered_at) as enteredH, hour(exited_at) as exitedH From access_logger); 

Select '0' as 'hour', count(*) as 'count' From aTemp Where (0 between enteredH and exitedH) 
UNION ALL 
Select '1' as 'hour', count(*) as 'count' From aTemp Where (1 between enteredH and exitedH) 
UNION ALL 
Select '2' as 'hour', count(*) as 'count' From aTemp Where (2 between enteredH and exitedH) 
UNION ALL 
Select '3' as 'hour', count(*) as 'count' From aTemp Where (3 between enteredH and exitedH) 
UNION ALL 
Select '4' as 'hour', count(*) as 'count' From aTemp Where (4 between enteredH and exitedH) 
UNION ALL 
Select '5' as 'hour', count(*) as 'count' From aTemp Where (5 between enteredH and exitedH) 
UNION ALL 
Select '6' as 'hour', count(*) as 'count' From aTemp Where (6 between enteredH and exitedH) 
UNION ALL 
Select '7' as 'hour', count(*) as 'count' From aTemp Where (7 between enteredH and exitedH) 
UNION ALL 
Select '8' as 'hour', count(*) as 'count' From aTemp Where (8 between enteredH and exitedH) 
UNION ALL 
Select '9' as 'hour', count(*) as 'count' From aTemp Where (9 between enteredH and exitedH) 
UNION ALL 
Select '10' as 'hour', count(*) as 'count' From aTemp Where (10 between enteredH and exitedH) 
UNION ALL 
Select '11' as 'hour', count(*) as 'count' From aTemp Where (11 between enteredH and exitedH) 
UNION ALL 
Select '12' as 'hour', count(*) as 'count' From aTemp Where (12 between enteredH and exitedH) 
UNION ALL 
Select '13' as 'hour', count(*) as 'count' From aTemp Where (13 between enteredH and exitedH) 
UNION ALL 
Select '14' as 'hour', count(*) as 'count' From aTemp Where (14 between enteredH and exitedH) 
UNION ALL 
Select '15' as 'hour', count(*) as 'count' From aTemp Where (15 between enteredH and exitedH) 
UNION ALL 
Select '16' as 'hour', count(*) as 'count' From aTemp Where (16 between enteredH and exitedH) 
UNION ALL 
Select '17' as 'hour', count(*) as 'count' From aTemp Where (17 between enteredH and exitedH) 
UNION ALL 
Select '18' as 'hour', count(*) as 'count' From aTemp Where (18 between enteredH and exitedH) 
UNION ALL 
Select '19' as 'hour', count(*) as 'count' From aTemp Where (19 between enteredH and exitedH) 
UNION ALL 
Select '20' as 'hour', count(*) as 'count' From aTemp Where (20 between enteredH and exitedH) 
UNION ALL 
Select '21' as 'hour', count(*) as 'count' From aTemp Where (21 between enteredH and exitedH) 
UNION ALL 
Select '22' as 'hour', count(*) as 'count' From aTemp Where (22 between enteredH and exitedH) 
UNION ALL 
Select '23' as 'hour', count(*) as 'count' From aTemp Where (23 between enteredH and exitedH) 
; 

DROP TEMPORARY TABLE IF EXISTS aTemp; 

(Select hour(entered_at)... From access_logger Where...) 쿼리에 사전 필터를 추가 할 수 있습니다.

관련 문제