일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- algorithm
- Sort
- lcap
- dfs
- 이분탐색
- 프로그래머스
- 매개변수 탐색
- SQL
- 트리
- 백트래킹
- 자료구조
- 스택
- domain model
- 알고리즘
- 멘딕스
- 집합
- MySQL
- Mendix
- Recursion
- 반효경교수님
- 완전탐색
- 가중치없는그래프
- 정렬
- git
- microflow
- 재귀
- 해시맵
- 그래프
- 자바
- Bruteforce
- Today
- Total
mondegreen
[SQL 코딩 테스트 대비-MySQL] GROUP BY 본문
1. 월별 잡은 물고기 수 구하기
1) 집계 함수를 사용한 뒤에는 WHERE 절을 사용할 수 없고 대신 HAVING 절을 사용해야 한다.
SELECT COUNT(ID) AS FISH_COUNT, MONTH(TIME) AS MONTH
FROM FISH_INFO
GROUP BY MONTH
HAVING COUNT(ID) > 0
ORDER BY 2
2. 물고기 종류 별 잡은 수 구하기
1) SELECT 문에서 FISH_NAME을 사용하고 싶다면 GROUP BY 함수에서 같이 집계해줘야 한다..
SELECT COUNT(ID) AS FISH_COUNT, FISH_NAME
FROM FISH_INFO
INNER JOIN FISH_NAME_INFO USING (FISH_TYPE)
GROUP BY FISH_TYPE, FISH_NAME
ORDER BY COUNT(ID) DESC
3. 노선별 평균 역 사이 거리 조회하기
1) 여기서 ORDER BY를 할 때 단순히 2로 처리해버리면 문자열인 상태기 때문에 원칙적으로 정렬이 되지 않는 것이 맞고 틀리다고 나온다. 따라서 정렬할 때 숫자로 처리할 수 있도록 직접 입력해주자.
SELECT ROUTE,
CONCAT(ROUND(SUM(D_BETWEEN_DIST), 1),'km') AS TOTAL_DISTANCE,
CONCAT(ROUND(AVG(D_BETWEEN_DIST), 2), 'km') AS AVERAGE_DISTANCE
FROM SUBWAY_DISTANCE
GROUP BY ROUTE
ORDER BY ROUND(SUM(D_BETWEEN_DIST), 1) DESC
4. 조건에 맞는 총 거래금액 조회하기
SELECT USER_ID, NICKNAME, SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD AS A
INNER JOIN USED_GOODS_USER AS B ON A.WRITER_ID = B.USER_ID
WHERE A.STATUS = "DONE"
GROUP BY USER_ID
HAVING SUM(PRICE) >=700000
ORDER BY 3 ASC
SELECT USER_ID, NICKNAME, SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD AS A, USED_GOODS_USER AS B
WHERE A.WRITER_ID = B.USER_ID
AND A.STATUS = "DONE"
GROUP BY USER_ID
HAVING SUM(PRICE) >=700000
ORDER BY 3 ASC
5. 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기(짱 복잡)
[문제] CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요. 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.
아래 서브쿼리가 "대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서" 에 해당하는 부분. 문제가.. 하라는대로 ...해야겠다..
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(CAR_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
AND CAR_ID IN (SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY CAR_ID
HAVING COUNT(CAR_ID) >=5
)
GROUP BY MONTH(START_DATE), CAR_ID
ORDER BY MONTH(START_DATE) ASC, CAR_ID DESC
아래 코드는 틀린 코드인데 그 이유는 먼저 월과 자동차별로 묶기 때문에 각 월에서 5회 이상이 아닌 차들은 제외되고, 문제에서 요구하는 총 3개월 간의 대여기록 5회 이상을 추출해내지 못한다. 따라서 서브 쿼리로 총 3개월 간의 대여횟수가 5회 이상인 차량의 아이디를 먼저 추출하고 그 안에서 월별과 차량 아이디로 구분해서 출력해줘야 하는 것이다.(개운)
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(CAR_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY MONTH(START_DATE), CAR_ID
HAVING COUNT(CAR_ID) >=5
ORDER BY MONTH(START_DATE) ASC, CAR_ID DESC
6. 즐겨찾기가 가장 많은 식당 정보 출력하기
[문제] REST_INFO 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류, ID, 식당 이름, 즐겨찾기수를 조회하는 SQL문을 작성해주세요. 이때 결과는 음식 종류를 기준으로 내림차순 정렬해주세요.
이제 WITH 구문으로 재사용 가능한 서브쿼리를 작성하는 데 많이 익숙해진 것 같다. 일단 음식 종류로 그룹핑을 하고 종류에 속하는 음식 중 가장 많은 즐겨찾기를 보유한 행을 추출한다. 그 행들을 가진 테이블과 원래 테이블을 조인해서 동일한 음식 종류이면서 즐겨찾기 수가 같은 행의 정보만 추출하는 방식으로 구현한다.
WITH B AS
(
SELECT FOOD_TYPE, MAX(FAVORITES) AS TMP
FROM REST_INFO
GROUP BY FOOD_TYPE
)
SELECT A.FOOD_TYPE, A.REST_ID, A.REST_NAME, A.FAVORITES
FROM REST_INFO AS A, B
WHERE A.FOOD_TYPE = B.FOOD_TYPE
AND A.FAVORITES = B.TMP
ORDER BY 1 DESC
7. 카테고리 별 도서 판매량 집계하기
[문제] 2022년 1월의 카테고리 별 도서 판매량을 합산하고, 카테고리(CATEGORY), 총 판매량(TOTAL_SALES) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 카테고리명을 기준으로 오름차순 정렬해주세요.
먼저 조인을 통해 도서별 판매량 컬럼을 추가한 테이블을 생성해주고 문제에서 제시한 기간에 해당하는 데이터에 대해서 카테고리별로 그룹핑해서 출력하면 된다.
WITH TMP AS
(
SELECT BOOK_ID, CATEGORY, SALES, SALES_DATE
FROM BOOK_SALES AS A
INNER JOIN BOOK USING (BOOK_ID)
)
SELECT CATEGORY, SUM(SALES) AS TOTAL_SALES
FROM TMP
WHERE TMP.SALES_DATE LIKE "2022-01%"
GROUP BY CATEGORY
ORDER BY 1
8. 부서별 평균 연봉 조회하기
[문제] HR_DEPARTMENT와 HR_EMPLOYEES 테이블을 이용해 부서별 평균 연봉을 조회하려 합니다. 부서별로 부서 ID, 영문 부서명, 평균 연봉을 조회하는 SQL문을 작성해주세요. 평균연봉은 소수점 첫째 자리에서 반올림하고 컬럼명은 AVG_SAL로 해주세요. 결과는 부서별 평균 연봉을 기준으로 내림차순 정렬해주세요.
부서별로 평균 연봉을 추출한 테이블에 대해서 부서별 정보를 조인해서 부서별 정보와 연봉을 출력하면 된다.
WITH TMP AS
(
SELECT DEPT_ID, AVG(SAL) AS SAL
FROM HR_EMPLOYEES
GROUP BY DEPT_ID
)
SELECT TMP.DEPT_ID, B.DEPT_NAME_EN, ROUND(TMP.SAL, 0) AS AVG_SAL
FROM TMP
INNER JOIN HR_DEPARTMENT AS B
ON TMP.DEPT_ID = B.DEPT_ID
ORDER BY 3 DESC
9. 가격대별 상품 개수 구하기
[문제] PRODUCT 테이블에서 만원 단위의 가격대 별로 상품 개수를 출력하는 SQL 문을 작성해주세요. 이때 컬럼명은 각각 컬럼명은 PRICE_GROUP, PRODUCTS로 지정해주시고 가격대 정보는 각 구간의 최소금액(10,000원 이상 ~ 20,000 미만인 구간인 경우 10,000)으로 표시해주세요. 결과는 가격대를 기준으로 오름차순 정렬해주세요.
반올림은 ROUND로 처리하고 버림의 경우 TRUNCATE로 처리하면 된다. 버림하는 자리 수를 적용하는 방식은 반올림과 동일하다. 소수점 자리인 경우 양수로 일의 자리 이상인 경우 음수로 버릴 자리 수를 표현해주면 된다.
SELECT TRUNCATE(PRICE, -4) AS PRICE_GROUP, COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY TRUNCATE(PRICE, -4)
ORDER BY TRUNCATE(PRICE, -4)
10. 조건에 맞는 사원 정보 조회하기
해당하는 연도의 행만을 대상으로 사원 번호로 그룹핑하고 점수의 합을 서브 쿼리로 먼저 구해준다. 이 테이블과 사원 정보 테이블을 이너조인해서 출력하면 된다.
[문제] HR_DEPARTMENT, HR_EMPLOYEES, HR_GRADE 테이블에서 2022년도 한해 평가 점수가 가장 높은 사원 정보를 조회하려 합니다. 2022년도 평가 점수가 가장 높은 사원들의 점수, 사번, 성명, 직책, 이메일을 조회하는 SQL문을 작성해주세요. 2022년도의 평가 점수는 상,하반기 점수의 합을 의미하고, 평가 점수를 나타내는 컬럼의 이름은 SCORE로 해주세요.
WITH TMP AS
(
SELECT EMP_NO, SUM(SCORE) AS SCORE
FROM HR_GRADE
WHERE YEAR = 2022
GROUP BY EMP_NO
)
SELECT TMP.SCORE, A.EMP_NO, A.EMP_NAME, A.POSITION, A.EMAIL
FROM HR_EMPLOYEES AS A
INNER JOIN TMP USING (EMP_NO)
ORDER BY SCORE DESC
LIMIT 1
11. 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기
1) CASE ~ END 구문을 활용해서 조건문을 구현할 수 있다.
2) WHEN, THEN, ELSE 구문을 활용해 필드를 채우고 새로운 컬럼을 만들 수 있다.
3) WITH 테이블명 AS (sql문) 을 활용해 참조할 테이블을 만든다.
4) CAR_ID가 한 개면 대여중이든 대여 가능이든 한 값만 존재하므로 그대로 활용한다.
5) CAR_ID가 두 개 이상이면 대여중과 대여 가능 모두 존재하는데 기준 날짜에 대여중인 경우가 있었기 때문에 가능여부가 대여중인 행만 활용한다.
WITH TEMP AS
(
SELECT CAR_ID,
CASE
WHEN '2022-10-16' BETWEEN START_DATE AND END_DATE
THEN "대여중"
ELSE "대여 가능"
END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID, AVAILABILITY -- 대여중과 대여 가능 모두 그룹핑 최상단에 있는 행만 딸려오지 않도록
ORDER BY 1 DESC
)
SELECT *
FROM TEMP
WHERE CAR_ID IN (
SELECT CAR_ID
FROM TEMP
GROUP BY CAR_ID
HAVING count(CAR_ID) = 1 -- 한개이면 대여중이든 대여가능이든 딱 한개만 출력
) OR AVAILABILITY = '대여중' -- 두개이면 대여중인것만 출력 해당 기간에 대여중이었다는 뜻이니까
ORDER BY 1 DESC;
'기타 > SQL' 카테고리의 다른 글
[SQL 코딩 테스트 대비-MySQL] STRING, DATE (0) | 2024.05.28 |
---|---|
[SQL 코딩 테스트 대비-MySQL] JOIN (0) | 2024.03.29 |
[SQL 코딩 테스트 대비-MySQL] SUM, MAX, MIN (0) | 2024.03.29 |
[SQL 코딩 테스트 대비-MySQL] SELECT (0) | 2024.03.26 |