월별로 주문 횟수를 출력하세요. 혹은 요일별로 주문 횟수를 출력하세요. 정도는 많이 나오는 쿼리 중 하나입니다. 오늘은 이 중, 요일별로 주문 횟수를 출력하는 방법을 알아보도록 하겠습니다. sakila 데이터 베이스에는 rental 테이블이 있습니다. 오늘은 그것을 가지고 놀아보겠습니다.
먼저, 두 함수를 보도록 하겠습니다.
date를 넘겨주면, dayofweek는 수를, dayname은 요일 이름을 돌려줍니다. 예를 들어서, date가 '2020-03-20'이라고 한다면, 후자의 리턴 값은 'Friday'가 됩니다. 문제는 dayofweek가 리턴하는 정수 값입니다.
위 표는 해당 date가 무슨 요일 (오른쪽) 일 때, 어떤 값을 리턴하는지 (왼쪽) 나타낸 것입니다. 만약에, '2020-03-20'이 넘어가면, 이 날은 금요일이므로 6이 리턴됩니다. 이제, 문제의 쿼리를 어떻게 구할 지 생각해 봅시다.
요일별로 구하는 것이기 때문에, group by 조건을 어떻게 주면 좋을까요?
둘 중 하나입니다. dayofweek(rental_date)를 기준으로 그룹을 매기거나, dayname(rental_date)를 기준으로 매기거나. 둘 중 하나입니다. 아래 쿼리를 작성해 보겠습니다.
그룹을 묶은 다음에 count(*) 이라는 집계 함수를 썼습니다. 이는, Row의 수를 셉니다. 우리는, 요일을 기준으로 그룹핑을 했기 때문에, 결론적으로는 요일별로 '대여' 요청이 몇 번 있는지가 2번째 열에 나타날 겁니다.
결과는 위와 같이 나옵니다.
이제, 조금 더 복잡한 쿼리를 보겠습니다. 결과값의 1번째 행은 일요일 날의 데이터, 2번째 행은 월요일 날의 데이터, ... , 7번째 행은 토요일의 데이터를 뽑고 싶습니다. 그리고, 1번째 열에는 숫자가 아닌 날짜 이름을 출력하고 싶습니다. 먼저, 결과 값에서, 1번째 열을 기준으로 정렬을 해야 합니다.
이 부분은 서브쿼리로 처리해줄 수 있습니다. t는 [결과 1]의 테이블입니다. 결과 1에서, _day 값을 기준으로 오름차 순으로 정렬해야 하므로, t._day 기준으로 오름차 정렬합니다. 8번째 줄이 그러한 일을 수행합니다. 다음에, t._day와 t.cc를 선택하면 됩니다.
결과 2는 위와 같습니다. 우리는 이 _day 필드의 1을 'Sunday'로, ... , 7을 'SATURDAY'로 바꾸고 싶습니다.
그러면, t._day를 가지고 처리할 수 있습니다. case 절로요. select 절에 서브 쿼리를 넣어버리면 됩니다.
t._day를 가지고, case 절을 돌렸습니다. 이 값이 1이면 'SUNDAY', ... , 7이면 'SATURDAY'를 리턴하게 했습니다. 뭔가 길어 보이는데요. 하나의 case 함수라고 생각하면 흐름이 대략적으로 이해가 가실 거라 생각합니다.
나머지는 동일합니다.
쿼리의 실행 결과는 위와 같습니다.
'코딩 > Sql' 카테고리의 다른 글
sql null 값이 왜 필요할까요? (0) | 2020.04.27 |
---|---|
sql group by 응용 : 시험을 최소 1번 이상 통과한 사람을 고르라. (4) | 2020.04.18 |
sql rank over 함수 : 알면 손쉽게 랭킹을 매길 수 있다. (17) | 2020.03.11 |
mysql distinct 절 : 중복된 결과를 제거한다. (10) | 2020.02.17 |
hash vs balanced tree : 언제 어떻게 써야 할까요? (6) | 2020.01.19 |
최근댓글