단일행 함수는 행 수를 바꾸지 않습니다. 이 한 문장이 다음 강의 집계 함수와 이 강을 가르는 전부입니다.
풀고 시작
문제 1. 값이 없을 때 대체값을 돌려주는 함수와, 두 값이 같으면 값이 없음을 돌려주는 함수를 순서대로 짝지은 것은?
NVL은 값이 없을 때 대체값을 주고, NULLIF는 두 값이 같으면 NULL을 돌려줍니다. NVL2는 값이 있을 때와 없을 때의 결과를 각각 지정하는 함수이고, COALESCE는 여러 인자 중 값이 있는 첫 번째를 돌려주는 함수입니다.
행마다 하나씩, 결과도 하나씩
단일행 함수(single row function)는 행 하나를 입력으로 받아 결과 하나를 돌려줍니다. 열 개 행에 함수를 쓰면 결과도 열 개입니다. 그래서 SELECT 절뿐 아니라 WHERE 절, ORDER BY 절에도 쓸 수 있습니다. 다음 강의 집계 함수가 여러 행을 하나로 줄이는 것과 정반대죠.
또 하나 기억할 성질은 중첩이 가능하다는 것입니다. 함수의 결과를 다시 다른 함수의 입력으로 넣을 수 있고, 안쪽부터 바깥쪽으로 계산됩니다. 그리고 인자가 NULL이면 결과도 대체로 NULL입니다. 이 규칙의 예외가 뒤에 볼 NULL 관련 함수들입니다.
문자와 숫자와 날짜
문자 함수는 자르고, 붙이고, 바꾸고, 세는 일을 합니다.
함수
하는 일
자주 나오는 포인트
LOWER, UPPER
소문자와 대문자로
대소문자를 무시한 비교에 씁니다
SUBSTR
부분 문자열 추출
시작 위치가 1부터입니다
LENGTH
글자 수
바이트 수를 세는 함수와 구분해야 합니다
LTRIM, RTRIM, TRIM
양옆 문자 제거
기본은 공백이고 지정도 됩니다
REPLACE
문자열 치환
찾을 문자열이 없으면 원본 그대로입니다
LPAD, RPAD
자릿수 채우기
지정 길이보다 길면 잘립니다
INSTR
위치 찾기
못 찾으면 0을 돌려줍니다
숫자 함수에서는 ROUND와 TRUNC의 차이가 단골입니다. ROUND는 반올림하고 TRUNC는 버립니다. 자릿수를 음수로 주면 소수점 왼쪽에서 작동한다는 점도 함께 기억해 두세요. 나머지를 구하는 MOD, 절대값 ABS, 올림 CEIL, 내림 FLOOR도 자주 나옵니다.
날짜 함수는 제품별 차이가 가장 큰 영역입니다. 현재 시각을 얻는 함수 이름이 다르고, 개월 수를 더하는 함수도 이름이 다릅니다. 대신 공통된 성질이 있습니다. 날짜에서 날짜를 빼면 일수가 나오고, 날짜에 숫자를 더하면 그만큼 뒤의 날짜가 나옵니다. 그리고 날짜와 문자를 서로 바꾸려면 형식을 지정한 변환 함수를 써야 합니다.
형 변환, 명시와 묵시
자료형을 바꾸는 방법은 두 가지입니다. 명시적 형 변환은 개발자가 변환 함수를 직접 쓰는 것이고, 묵시적 형 변환은 데이터베이스가 알아서 맞춰 주는 것입니다.
묵시적 변환은 편한 대신 두 가지 대가를 치릅니다. 첫째, 2강에서 본 것처럼 변환이 컬럼 쪽에 붙으면 인덱스를 쓸 수 없습니다. 둘째, 제품이 어느 쪽을 변환할지 우리가 정하지 않으므로 예상과 다른 결과나 오류가 날 수 있습니다. 문자 컬럼과 숫자를 비교했더니 문자에 숫자 아닌 값이 섞여 있어 변환 오류가 나는 상황이 대표적이죠. 그래서 명시적으로 쓰는 습관이 권장됩니다.
숫자와 날짜를 문자로 바꿀 때는 형식 문자열을 함께 줍니다. 연도 네 자리, 월 두 자리, 일 두 자리를 지정하는 표기가 그것입니다. 반대로 문자를 날짜로 바꿀 때도 같은 형식을 알려 줘야 하며, 형식을 생략하면 세션의 기본 설정에 따라 결과가 달라집니다. 같은 쿼리가 어제는 되고 오늘은 안 되는 사고의 흔한 원인입니다.
NULL을 다루는 함수들과 CASE
앞에서 인자가 NULL이면 결과도 NULL이라고 했는데, 그 규칙을 깨기 위해 존재하는 함수들이 있습니다.
NVL은 값이 없으면 지정한 대체값을 돌려줍니다. 표준 SQL에서는 COALESCE가 같은 일을 하며, 인자를 여러 개 받아 값이 있는 첫 번째를 돌려줍니다. NVL2는 값이 있을 때와 없을 때의 결과를 각각 지정합니다. NULLIF는 방향이 반대입니다. 두 값이 같으면 NULL을 돌려주고 다르면 첫 번째 값을 돌려줍니다. 이름이 비슷해서 헷갈리니 "NULLIF는 NULL을 만드는 함수"라고 붙여 두면 편합니다.
CASE 식은 조건 분기를 SQL 안에서 처리합니다. 두 가지 형태가 있습니다. 값이 무엇과 같은지를 비교하는 단순 형태와, 조건식을 나열하는 검색 형태입니다. 검색 형태가 훨씬 자유롭고, 범위 비교나 여러 컬럼을 함께 보는 조건도 쓸 수 있습니다.
CASE에서 기억할 두 가지가 있습니다. 위에서부터 순서대로 평가해 처음 참이 된 분기에서 멈춥니다. 그래서 조건의 순서가 결과를 바꿉니다. 그리고 어느 조건에도 걸리지 않으면 ELSE의 값이 나오고, ELSE를 생략하면 NULL이 나옵니다. ELSE를 빼먹었는데 결과에 빈칸이 생기는 이유가 이것입니다. 11강 윈도우 함수와 10강 그룹 함수에서 CASE가 계속 등장하니 여기서 확실히 잡아 두는 편이 좋습니다.
인출 문제
문제 1. 단일행 함수에 대한 설명으로 옳지 않은 것은?
여러 행을 하나로 줄이는 것은 다음 강에서 볼 집계 함수의 일입니다. 단일행 함수는 행 수를 바꾸지 않기 때문에 조건절과 정렬절에서도 자유롭게 쓸 수 있습니다.
문제 2. 두 값이 같으면 NULL을, 다르면 첫 번째 값을 돌려주는 함수는?
NULLIF는 이름 그대로 조건이 맞으면 NULL을 만들어 냅니다. NVL과 COALESCE는 반대로 NULL을 없애는 쪽이고, NVL2는 값의 유무에 따라 서로 다른 결과를 고르는 함수입니다.
문제 3. CASE 식에서 ELSE를 생략했고 어떤 조건에도 해당하지 않는 행이 있을 때의 결과는?
ELSE가 없으면 걸리지 않은 행의 결과는 NULL입니다. 결과에 빈칸이 보이는데 원인을 못 찾는 상황의 상당수가 ELSE 누락입니다.
문제 4. 묵시적 형 변환에 대한 설명으로 옳은 것은?
묵시적 변환은 편하지만 변환 방향을 우리가 정하지 못합니다. 컬럼 쪽이 변환되면 인덱스가 무력해지고, 변환할 수 없는 값이 섞여 있으면 실행 중에 오류가 날 수도 있습니다.
더 풀기
출제기준의 세세항목을 따라 이 강의 범위에서 새로 낸 문제입니다. 모의고사도 여기에서 뽑습니다.
묶음 1
문제 1. 단일행 함수의 특징으로 가장 알맞은 것은?
단일행 함수는 입력 행 수와 출력 행 수가 같습니다. 여러 행을 줄이는 것은 집계 함수입니다.
문제 2. 다음 중 단일행 함수가 아닌 것은?
평균은 여러 행을 하나로 줄이는 집계 함수입니다. 나머지는 모두 행마다 결과가 나옵니다.
문제 3. 문자열의 일부를 잘라 내는 함수에서 시작 위치를 일로 주면 어디부터 잘리나요?
SQL의 문자 위치는 일부터 시작합니다. 영부터 시작하는 프로그래밍 언어의 습관과 달라 자주 틀리는 자리입니다.
문제 4. 문자열 데이터베이스에서 세 번째 글자부터 네 글자를 잘라 내면 결과는?
세 번째 글자는 이이고 거기서 네 글자를 세면 이터베이입니다.
문제 5. 문자열 양쪽 끝의 공백을 없애는 함수의 이름으로 알맞은 것은?
TRIM이 앞뒤 공백을 제거합니다. 한쪽만 제거하는 LTRIM과 RTRIM도 있습니다.
문제 6. 문자열 안에서 특정 문자가 처음 나타나는 위치를 찾는 함수는?
INSTR은 위치를 숫자로 돌려줍니다. 찾지 못하면 영을 돌려주는 것이 일반적입니다.
문제 7. 문자열 안의 특정 부분을 다른 문자열로 바꾸는 함수는?
REPLACE는 찾을 문자열과 바꿀 문자열을 받아 모든 일치 부분을 바꿉니다.
문제 8. 문자열을 지정한 길이가 되도록 왼쪽에 특정 문자를 채우는 함수는?
LPAD는 왼쪽을 채우고 RPAD는 오른쪽을 채웁니다. 번호를 자릿수에 맞춰 영으로 채울 때 자주 씁니다.