본문 바로가기
  • 실행력이 모든걸 결정한다
DB/SQL Problems

[SQL-GROUP BY, 난이도 중상] 입양 시각 구하기(2)

by 김코더 김주역 2020. 12. 7.
반응형

 

kimcoder.tistory.com/208?category=897810

 

[SQL-GROUP BY, 난이도 중] 입양 시각 구하기(1)

해설 : DATETIME을 보면 "0000-00-00 00:00:00" 형식을 지키고 있다. 여기서 HOUR 함수를 이용하면 쉽게 "시" 만 추출할 수 있다. 그리고 테이블의 레코드 수는 COUNT 함수로 구할 수 있다. 시간대 별 입양 건

kimcoder.tistory.com

 

해설 : 위에 링크로 첨부한 입양 시각 구하기(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 값인 레코드의 수를 추출한다.

 

 

반응형

댓글