지난 며칠 동안 아침에 SQL 문제를 풀면서 학습한 내용들을 정리했습니다.
1. NULL의 올바른 처리
-
비교:
NULL은 ‘값이 없음’을 의미하는 특별한 상태이므로, 등호(=)로 비교할 수 없습니다. 별도의 설정을 하지 않는 한IS NULL또는IS NOT NULL연산자를 사용해야 합니다. -
치환:
NULL값을 다른 값으로 대체할 때는 MySQL에서 제공하는IFNULL도 있지만, SQL 표준 함수인COALESCE(컬럼, '대체값')도 알아두면 좋습니다.-- 전화번호가 없으면(NULL) 'None'로 표시 SELECT animal_id, COALESCE(phone_number, 'None') AS phone FROM ANIMAL_INS WHERE adopter_name IS NULL; -- 입양자 이름이 없는 동물 조회
2. IF와 CASE
-
간단한 분기는
IF(조건, 참, 거짓)(MySQL)이 간결하고, 복잡한 분기 처리는 모든 DB에서 호환되는 표준CASE WHEN ... THEN ... END구문을 사용하면 좋을 것 같습니다.-- MySQL의 IF() 함수 SELECT price, IF(price >= 10000, '고가', '저가') AS price_category FROM PRODUCTS; -- 표준 CASE 문 SELECT price, CASE WHEN price >= 10000 THEN '고가' WHEN price >= 5000 THEN '중저가' ELSE '저가' END AS price_category FROM PRODUCTS;
3. 다중 조건 검색
IN: 여러OR조건을 간결하게 표현하는 표준 방식입니다.BETWEEN: 특정 범위를 확인할 때 가독성이 좋습니다.REGEXP: 여러 키워드를 정규표현식을 이용하여 OR 조건으로 찾을 때 간결합니다. (MySQL)FIND_IN_SET: 콤마(,)로 구분된 목록에서 정확한 단어를 찾을 때 유용합니다. (MySQL)
SELECT * FROM CARS
WHERE
car_type IN ('세단', 'SUV') -- car_type = '세단' OR car_type = 'SUV'
AND year BETWEEN 2020 AND 2022 -- year >= 2020 AND year <= 2022
AND options REGEXP '열선시트|통풍시트' -- '열선시트' 또는 '통풍시트' 포함
AND FIND_IN_SET('스마트키', options) > 0; -- '스마트키' 옵션이 정확히 존재
4. GROUP BY, WHERE 절에서의 별칭(Alias)
SELECT 절은 GROUP BY 절이나 WHERE절보다 나중에 실행되므로, 표준 SQL에서는 GROUP BY 혹은 WHERE에 SELECT에서 만든 별칭을 사용할 수 없습니다. 따라서, 실제 표현식을 써주는 것이 좋습니다.
-- 좋은 예시 (표준)
SELECT LEFT(product_code, 2) AS category, COUNT(*)
FROM PRODUCTS
GROUP BY LEFT(product_code, 2);
-- 나쁜 예시 (MySQL에서만 허용)
SELECT LEFT(product_code, 2) AS category, COUNT(*)
FROM PRODUCTS
GROUP BY category;
-
SQL 쿼리 실행 순서: SQL은 작성된 순서가 아닌, 정해진 논리적 순서에 따라 실행됩니다.
FROM→WHERE→GROUP BY→HAVING→SELECT→DISTINCT→ORDER BY→LIMIT
-
쿼리 성능 최적화 (SARGable):
WHERE절에서 인덱스가 걸린 컬럼 자체에 함수를 적용하면 인덱스를 사용하지 못해 성능이 저하됩니다. 컬럼은 그대로 두고, 비교하는 값을 가공하면 인덱스를 사용하여 쿼리 실행 속도를 높일 수 있습니다.SARGable: 관계형 데이터베이스에서는 DBMS 엔진이 인덱스를 활용하여 쿼리 실행 속도를 높일 수 있는 경우 쿼리의 조건 (Search ARGument ABEL)
-- 인덱스 사용 불가 WHERE DATE_FORMAT(order_date, '%Y-%m') = '2025-07'; -- 인덱스 사용 가능 WHERE order_date >= '2025-07-01' AND order_date < '2025-08-01';
5. EXTRACT(추출내용 FROM 날짜/시간)
-
YEAR(날짜)는 간편하지만 MySQL 등 여러 벤더에서 지원하는 함수이며, ANSI 표준은 아닙니다. 이식성을 고려해야 하는 상황을 대비하기 위해 ANSI 표준인EXTRACT도 알아두려고 합니다.-- MySQL YEAR 사용 SELECT * FROM ORDERS WHERE YEAR(order_date) = 2025; -- ANSI 표준 SELECT * FROM ORDERS WHERE EXTRACT(YEAR FROM order_date) = 2025;
참고