연습 풀이 전략
프로그래머스에서 6가지의 카테고리 별로 나누어 연습해볼 수 있는데,
SELECT 문에서 JOIN 도 나오기도 한다. 그래서 한 개씩 여기저기 들르면서 푸는 것을 추천한다.
실전 풀이 전략
SQL 관련 코테가 예정되어 있어서, 일단 실전 풀이 전략은 다음과 같이 세우기로 했다.
1. 일단 테스트 시험까지 응시해본 결과, 임시로 나오는 테스트케이스에 맞게 예제가 나오지 않는다.🥲 데이터를 눈으로 확인할 수 있는 방법이 있긴 하다.😏 SELECT * FROM TABLE명 ; 하면 얼추 나온다.
2. 백준처럼 맞았습니다!! 를 확인할 수 없다. 그래서 테스트케이스 답과 모두 일치함에도 불구하고 틀릴 수 있다.(조건 등을 하나씩 빼먹을 경우) 조건 하나하나 잘 파악해서 쓰자(성별, 카테고리 제한 등)
3. ORDER BY ~ DESC 등은 무조건 나오는 것 같다. 문제를 많이 풀어보면서 실수를 줄이자!!4. 국어적인 실수를 잘 보자ㅠㅠ JOIN 조건 잘 보자! 문제 잘 읽자!
주로 나오는 메소드 및 키워드 정리
1. GROUP BY
'~별'의 뉘앙스가 나면 GROUP BY를 의심하자!
2. LIKE ' '
단어에 특정 문자열이 포함되어있는지 확인하는 방법이다. 주로 %와 같이 쓰인다.
3. DATE_FORMAT(DATE, '%Y-%M-%D') AS 'DATE'.
이 때 Y,M,D는 대문자/소문자에 따라 출력 형태가 다름.
만약 MONTH만 추출하고 싶다면 MONTH(DATE) AS MONTH 로 추출 가능하다.
4. AS ~ (칼럼 명 바꿀 때 사용)
5. 평균 AVG, 반올림 ROUND(숫자,어디서), 반내림 TRUNCATE(숫자, 어디서)
6. 특정 필드명 우선정렬
ORDER BY FIELD(COLUMN, 1순위, 2순위 ..)
7. IFNULL(COLUMN명, "NULL값일 때 대체 값")
8. CASE
CASE
WHEN 조건식 1 THEN 식1
WHEN 조건식 2 THEN 식2
WHEN 조건식 3 THEN 식3
..
ELSE 조건에 맞는 경우가 없을 경우 실행할 식
END
EX)
SELECT
CASE
WHEN NAME IS NULL THEN "NONE"
ELSE NAME
END AS NAME
FROM ANIMAL_INS
9. WHERE / HAVING
WHERE 과 구분되는 HAVING의 특징은 그룹으로 묶은 후(GROUP BY) 그 안에서 처리한다!
10. GROUP BY 는 여러개를 기준으로 묶을 수도 있다.
11. 서브쿼리
WHERE 절 속 또 다른 SELECT 문 사용. IN이나 부등호(>,=,<)와 함께 쓰이는 경우가 많다.
12. WITH ~ AS
11번과 같은 맥락으로 가상테이블을 만들 수 있는 방법이다. 형태는 아래와 같다.
WITH TEMPTABLE AS
( SELECT ~ FROM ~ )
13. JOIN / LEFT OUTER JOIN (=LEFT JOIN) / RIGHT OUTER JOIN(=RIGHT JOIN)
LEFT JOIN은 LEFT에 해당하는 모든 행을 조회하고, RIGHT에 JOIN되는 값이 없다면 RIGHT 행값은 NULL처리 된다.
14. RECURSIVE
TIME이라는 테이블에 0부터 24까지의 값이 존재하는 HOUR COLUMN을 넣고 싶을 때
WITH RECURSIVE TIME AS (
SELECT 0 AS HOUR # 비반복문. 무조건 필수
UNION ALL #다음에 이어붙어야 할 때 사용
SELECT HOUR + 1 FROM TIME WHERE HOUR < 23 #정지 조건 필요할 때 사용
)
SELECT * FROM TIME
15. 변수할당
SET @변수이름 := 대입값;
16. 정규표현식
기본 연산자보다 복잡한 문자열 조건을 걸어 데이터를 검색할 때 사용
# 정규표현식을 사용하지 않을 때
SELECT *
FROM tbl
WHERE data like '%길%'
OR data like '%로%'
OR data like '%그%'
# 정규표현식을 사용할 때
SELECT *
FROM tbl
WHERE data REGEXP '길|로|그'
17. UNION과 UNION ALL 차이 ( 합집합 )
UNION - 중복된 ROW는 제거
UNION ALL - 모든 컬럼값이 같은 ROW도 결과로 보여준다. 중복제거 하지 않는다.
18. INTERSECT ( 교집합 ), MINUS ( 차집합 )
19.
오답 체크
문제1
-- 처음 오답 코드
SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY='과자' OR CATEGORY='국' OR CATEGORY='김치' OR CATEGORY='식용유'
GROUP BY CATEGORY
ORDER BY MAX_PRICE DESC
이 문제는 SUBQUERY를 사용해야 한다.
조건에 해당하는 애들을 기준으로 -> GROUPING 하여 처리해야 하는 문제이므로!
--정답 코드
SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY IN ('과자','국','김치' ,'식용유')
AND PRICE IN (SELECT MAX(PRICE) FROM FOOD_PRODUCT GROUP BY CATEGORY)
GROUP BY CATEGORY
ORDER BY MAX_PRICE DESC
문제2
-- 처음 오답 코드
SELECT CAR_ID,
CASE
WHEN START_DATE<='2022-10-16' AND END_DATE>='2022-10-16' THEN '대여중'
ELSE '대여 가능'
END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC
틀린 이유는 위의 예시에서도 확인해볼 수 있는데, CAR_ID는 DISTINCT하지 않다. 즉 똑같은 CAR_ID인 3번째 '2'와 6번째 '2'에서 3번째는 조건에 해당하지 않지만 6번째는 해당한다. 이 때문에 '하나라도' 해당을 한다면 조건에 처리해주어야 하므로 SUBQUERY를 써줘야 한다.
--정답코드
SELECT CAR_ID,
CASE
WHEN CAR_ID IN ( -- 만약 하나라도 해당을 한다면!?
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE<='2022-10-16' AND END_DATE>='2022-10-16') THEN '대여중'
ELSE '대여 가능'
END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC
또한 DISTINCT를 사용하면 안된다. 이는 CAR_ID 뿐만 아니라 AVAILABILITY도 함께 출력해야 한다.
내가 맨 처음 썼던 SQL문은 그냥 해당 CAR_ID를 가진 것 중에 가장 상위 조건만 출력됨을 알 수 있다.
(굳이 DISTINCT를 사용하려면 AVAILABILITY가 '대여중'인 것과 '대여 가능'한 로직을 따로 분리해서 출력해야 한다.
문제3
'하나라도' 풀이에는 DISTINCT도 사실 많이 사용된다.
위에서 DISTINCT를 사용하면 안되는 이유를 아래에서 몸소(?) 확인할 수 있다.
이는 USER_ID가 한 번이라도 나왔는지 안 나왔는지가 중요한 문제이고 위에 문제처럼 종속되어 출력해야 하는 다른 COLUMN이 존재하지 않으므로, DISTINCT를 사용해도 괜찮다.
SELECT YEAR(SALES_DATE) AS YEAR, MONTH(SALES_DATE) AS MONTH, GENDER, COUNT(DISTINCT(O.USER_ID)) AS USERS
FROM USER_INFO U JOIN ONLINE_SALE O ON U.USER_ID = O.USER_ID
WHERE GENDER IS NOT NULL
GROUP BY YEAR, MONTH, GENDER
ORDER BY YEAR, MONTH, GENDER
'BackEnd' 카테고리의 다른 글
[후기] 객체지향의 사실과 오해 (4) | 2023.08.04 |
---|---|
[MYSQL] MySQL - Advanced Class 수학 관련 함수 (0) | 2023.02.28 |
[MYSQL] MySQL - Advanced Class 문자열 (0) | 2023.02.27 |
[ERD|API] ERD 및 API 설계 (1) | 2023.01.06 |
배달의 민족 간단한 DB 설계 (0) | 2022.10.28 |