SQL Study List
SQL을 작성하면서 새롭게 알게 된 사실이나 알아두어야 하는 내용을 정리했다.
1. case - when 조건에 해당하지 않을 경우, 어떤 값 반환될까?
테이블 : TEST
이름 | 유형 | KEY | comment |
---|---|---|---|
id | int | PK | 테이블 id |
name | varchar | 이름 | |
time | varchar | 총 시간 | |
pos | varchar | 현재 위치 |
위와 같은 테이블이 있다고 가정하자.
특정 버튼을 누르면 아래의 sql이 실행된다.
1
2
3
4
5
6
7
8
update test_table
set pos =
case
when ifnull(time, 0) = 0 then 0
when ifnull(pos, 0) > ifnull(time, 0) then pos
when ifnull(time,0) > ifnull(pos, 0) then time
end
where id = 1;
만약 pos와 time이 100으로 같다면, case의 세 조건 중 어느 곳에도 해당되지 않기 때문에 NULL을 반환한다. 즉, pos에는 NULL이 할당된다.
2. select 1
1
select 1;
위와 같이 사용할 경우, 아래와 같은 결과를 반환한다.
test 테이블은 아래와 같은 데이터를 가진다.
id | name |
---|---|
1 | A |
2 | B |
3 | C |
이 테이블을 가지고 아래의 sql을 실행하면
1
2
select 1
from test;
다음과 같은 결과가 반환된다.
1 |
---|
1 |
1 |
1 |
즉, 모든 행의 값이 1이 된다.
sql에서 1은 true를 의미하기도 한다. 때문에 조건절의 not exists or exists 안에 있는 서브 쿼리에서 많이 사용된다.
1
2
3
4
5
6
7
8
9
SELECT
CASE
WHEN EXISTS (
SELECT 1
FROM test
WHERE id = 1
) THEN '존재합니다'
ELSE '존재하지 않습니다'
END AS 존재여부;
결과값은 아래와 같다.
존재여부 |
---|
존재합니다. |
즉, not exists나 exists는 실제로 1이라는 값을 반환하는 것이 아니라 조건절에 해당하는 행이 존재하는지를 확인한다.
위 예시에서는 id=1인 행이 존재하기 때문에 ‘존재합니다’ 가 반환된다.
3. concat과 null
쿼리를 확인하다가 이상한 점을 발견했다. IF 조건문 없이 단순히 CONCAT 함수만 사용했는데, 어떤 경우엔 문자열이 잘 붙어서 나오고, 어떤 경우엔 결과가 NULL로 반환되는 것이다. 처음엔 쿼리 로직이 잘못된 줄 알았지만, 알고 보니 이건 CONCAT 함수의 동작 방식 때문이었다.
SQL에서 CONCAT(a, b, c)처럼 여러 문자열을 이어붙일 때, 우리가 흔히 기대하는 동작은 null이 아닌 값들만 이어붙이는 것이다. 하지만 실제로는 그렇지 않다. CONCAT 함수는 인자 중 하나라도 NULL이면 전체 결과를 NULL로 반환한다.
1
2
SELECT CONCAT('Hello', NULL, 'World');
-- 결과: NULL
반면에 아래처럼 NULL이 아닌 값만 있으면 정상적으로 동작한다.
1
2
SELECT CONCAT('Hello', ' ', 'World');
-- 결과: Hello World
null이 반환되는 문제를 피하려면 IFNULL() 또는 COALESCE() 같은 함수로 NULL 값을 미리 처리해주는 것이 좋다.
1
SELECT CONCAT(IFNULL(col1, ''), IFNULL(col2, ''), IFNULL(col3, ''));