kimcoder.tistory.com/208?category=897810
해설 : 위에 링크로 첨부한 입양 시각 구하기(1) 과의 차이점은 COUNT(*) 값이 0인 레코드 포함 여부이다.
이번 문제에서는 0부터 23까지 모든 시간대 별로 입양 시각 분포를 구해야 한다.
이 문제는 곰곰히 생각해도 잘 풀리지 않아서 검색을 해봤는데 핵심은 변수를 사용한다는 점이었다.
이 문제에서 요구하는 GROUP BY를 사용하여 푸는 방법과 GROUP BY를 쓰지 않고 더 간단하게 푸는 방법 2가지를 소개한다.
1) GROUP BY 사용
SET @H = -1;
SELECT H.HOUR, COUNT(HOUR(AO.DATETIME)) FROM
(SELECT (@H:=@H+1) HOUR
FROM ANIMAL_OUTS WHERE @H<23) AS H
LEFT JOIN ANIMAL_OUTS AS AO
ON H.HOUR = HOUR(AO.DATETIME)
GROUP BY H.HOUR
ORDER BY H.HOUR;
변수 @H = -1 로 초기화. 변수 @H에 의해 0번 부터 23번까지 레코드가 선택되었고 이 테이블 명을 H로 지정 했다.
단 하나의 필드 HOUR(0~23)를 갖는 테이블(H) 과 ANIMAL_OUTS 테이블(AO)를 LEFT JOIN 해주는 방법이다.
LEFT JOIN은 왼쪽 테이블의 JOIN기준으로 지정한 필드의 모든 레코드를 살려주는 JOIN 방법이다.
JOIN은 H.HOUR 와 HOUR(AO.DATETIME) 값이 같은 레코드를 기준으로 수행한다.
LEFT JOIN 덕분에 H.HOUR 필드의 모든 레코드(0~23)가 살았으므로 0부터 23까지의 모든 시간대를 볼 수 있는 것이다.
모든 시간대를 보기 위해 역시 GROUP BY, ORDER BY도 H.HOUR를 기준으로 지정한다.
2번째 줄에 있는 SELECT 문을 살펴보기 전에 이 문제의 요구 사항을 다시 한번 되새기자면,
시간대(0~23) 별 입양 건수를 구하는 것이다.
GROUP BY문에 의해 H.HOUR(시간대) 마다, AO 테이블의 해당 시간대의 레코드가 붙었기 때문에 SELECT의 2번째 필드는 각 특정 시간대의 레코드 수를 출력하도록 한 것이다.
2) GROUP BY 사용 X
SET @H=-1;
SELECT (@H := @H+1) HOUR,
(SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME)=@H) COUNT
FROM ANIMAL_OUTS
WHERE @H<23;
변수 @H = -1 로 초기화.
SELECT의 첫 번째 필드는 HOUR 이고, @H 변수로 인하여 HOUR필드값은 0~23까지 표시된다.
그리고 메인 SELECT의 두 번째 필드 자체를 또 다른 SELECT 문으로 선언해 준 모습이다.
이 SELECT 문은 DATETIME의 HOUR 부분이 @H 값인 레코드의 수를 추출한다.
'DB > SQL Problems' 카테고리의 다른 글
[SQL-SUM,MAX,MIN, 난이도 하] 최댓값 구하기 (0) | 2020.12.08 |
---|---|
[SQL-SUM,MAX,MIN, 난이도 하] 최솟값 구하기 (0) | 2020.12.08 |
[SQL-GROUP BY, 난이도 중] 입양 시각 구하기(1) (0) | 2020.12.07 |
[SQL-JOIN, 난이도 중하] 없어진 기록 찾기 (0) | 2020.12.07 |
[SQL-JOIN, 난이도 중하] 있었는데요 없었습니다 (0) | 2020.12.07 |
댓글