SQLD: 함수, WHERE
함수
함수는 입력 값을 넣어 특정한 기능을 통해 결과 값을 출력해준다.
함수가 어떻게 만들어져 있는지는 알 필요가 없으며, 입력 개수, 출력 개수, 그리고 기능만 알면 된다.
내장형 함수
내장형 함수란 DBNS에 미리 만들어져 있어 사용이 가능한 함수이다.
문자형 함수: UPPER, SUBSTR, TRIM, REPLACE …
숫자형 함수: MOD, ROUND …
날짜형 함수: SYSDATE …
UPPER
1
2
3
SELECT UPPER('abcde123@@') AS UPPER사용
FROM DUAL; -- dual은 테스트할 때 쓰이는 테이블
UPPER는 문자열뿐만이 아니라 컬럼도 선택할 수 있다:
1
2
3
SELECT CUST_ID, PASSWD, UPPER(PASSWD) AS 패스워드대문자
FROM TB_CUST
SUBSTR
SUBSTR(문자형 리터럴, 시작위치, 길이)
형식으로 사용한다.
특정 문자형 리터럴의 시작위치부터 길이만큼 잘라서 출력한다.
TRIM
TRIM은 공백을 제거한다.
SELECT TRIM(' 안녕하세요 ')
를 하면 ‘안녕하세요’가 출력된다.
REPLACE
REPLACE는 특정 문자를 다른 문자로 변경해준다.
ROUND
ROUND는 반올림한 결과를 출력해준다.
입력 값으로 숫자형 리터럴 2개를 받으며, 첫 수는 실수이며 두번째 수는 소수점의 자리 수이다.
1
2
SELECT ROUND(1.452, 2), ROUND(1.452, 1)
FROM DUAL
결과: 1.42, 1.5
자료형
문자, 숫자, 날짜가 있다. 이들을 변환하는 함수들은 TO_DATE()
, TO_CHAR
, TO_NUMBER
이다.
날짜
SYSDATE는 현재 날짜를 날짜형 데이터로 출력하는 날짜형 함수이다. 날짜의 포맷은 다음과 같다:
YYYY: 연도 4자리
MM: 월 2자리
DD: 일 2자리
HH24: 24시간제 시간 (오후 1시 -> 13시)
HH: 12시간제
MI: 분
SS: 초
1
2
3
4
5
SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') FROM DUAL;
SELECT TO_DATE('20240817', 'YYYY/MM/DD') FROM DUAL; -- 출력값: 2024-08-17 00:00:00
SELECT TO_DATE('2024081701141212', 'YYYY/MM/DD HH24:MI:SS') FROM DUAL; -- 출력값: 2024-08-17 14:12:12
연산을 하기 전에 먼저 형변환이 발생한다. 형 변환의 우선순위는 문자형 < 숫자형 < 날짜형 이다. 즉, 날짜형이 가장 우선순위가 높다.
1
SELECT CUST_NAME + 1000 FROM TB_CUST;
위의 예시와 같이 사칙 연산을 할 때 CUST_NAME은 문자형이고, 1000은 숫자형이면 형을 통일해야 하는데 문자형을 숫자형에 맞춰준다. 즉, TO_NUMBER(CUST_NAME)
이 먼저 발생한다는 것이다.
여기서 발생할 수 있는 문제는, CUST_NAME의 값이 숫자로 변환될 수 있는 형태가 아니라면 INVALID NUMBER이라는 오류가 뜰 수 있다.
NULL
NULL은 정상적인 산술, 비교 연산 등이 불가능하다.
1
SELECT 3 + NULL FROM DUAL; -- (null)
NULL은 아직 정해지지 않은 값이기 때문에 NULL을 산술/비교 연산에 사용하면 결과값으로 NULL이 나온다.
NULL 함수란 NULL값을 대체할 수 있는 함수이다.
NVL(data1, data2)
- data1에 NULL값이 들어오면 data2를 출력하고, NULL이 아니면 data1을 출력한다.
1
2
3
4
SELECT CUST_ID
,PHONE_NO
,NVL(PHONE_NO, '연락처 없음') AS NVL적용;
FROM TB_CUST
NVL(PHONE_NO, '연락처 없음') AS NVL적용;
은 PHONE_NO가 있으면 이를 NVL적용 컬럼에 사용하고, 없으면 ‘연락처 없음’이라는 문구를 사용하겠다는 말이다.
DECODE(data1, data2, data3, data4 …)
- data1과 data2가 동일하면 data3를 출력하고, 그렇지 않으면 data4를 출력한다.
1
2
3
4
SELECT CUST_ID
,PHONE_NO
,DECODE(PHONE_NO, NULL, '연락처 없음', PHONE_NO) AS DECODE적용;
FROM TB_CUST
CASE 문법
SQL판 if-else문이다.
1
2
3
4
5
6
7
8
9
SELECT CUST_ID
,CUST_NAME
,ACT_POINT
,CASE WHEN ACT_POINT <= 1000 THEN '브론즈'
WHEN ACT_POINT <= 10000 THEN '실버'
WHEN ACT_POINT <= 100000 THEN '골드'
ELSE '마스터'
END AS 등급
FROM TB_CUST;
WHERE
SELECT * FROM TB_CUST
를 하면 모든 TB_CUST의 모든 행이 출력이 된다.
실무 상황에서는 수만 건의 행이 있을텐데 이렇게 하게 되면 비효율적이기 때문에, WHERE
절을 사용하여 원하는 내용만 출력할 수 있다.
1
2
3
SELECT CUST_ID, CUST_NAME, BIRTH_DY
FROM TB_CUST
WHERE MONEY = 10000;
모든 행을 출력하는 것이 아닌, MONEY가 10000인 곳만 출력하도록 WHERE
을 사용하여 만들 수 있다.
비교 조건은 =, > , <= 등을 사용하면 된다.
문제1: TB_PRD 테이블에서 PRD_TYPE이 ‘컴퓨터’인 대상의 모든 컬럼을 출력해주세요.
A:
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_TYPE = '컴퓨터';
문제2: TB_PRD 테이블에서 PRD_AMT가 1,000,000이상인 상품의 모든 컬럼을 출력해주세요. A:
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_AMT >= 1000000;
논리 조건은 AND, OR으로 추가적인 조건을 준다.
문제1: TB_CUST 테이블에서 CUST_ID가 ‘C0001’이고 PASSWD가 ‘pass111’인 대상의 모든 정보를 출력해주세요. A:
1
2
3
4
SELECT *
FROM TB_CUST
WHERE CUST_ID = 'C0001'
AND PASSWD = 'pass111';
문제2: TB_PRD 테이블에서 PRD_TYPE이 ‘컴퓨터’이거나 ‘스마트폰’인 대상의 모든 정보를 출력해주세요.
A:
1
2
3
4
SELECT *
FROM TB_PRD
WHERE PRD_TYPE = '컴퓨터'
OR PRD_TYPE = '스마트폰';
부정 연산은 조건에 NOT 개념이 붙은 것이다. 사용 방식은 != 연산자를 쓰는 것과 조건 앞에 ‘NOT’을 쓰는 방법이 있다.
문제1: TB_PRD 테이블에서 PRD_TYPE이 ‘가전’이 아닌 데이터를 출력해주세요.
A:
1
2
3
4
5
6
7
SELECT *
FROM TB_PRD
WHERE NOT PRD_TYPE = '가전';
--
SELECT *
FROM TB_PRD
WHERE PRD_TYPE != '가전';
NULL 연산은 IS NULL/IS NOT NULL로 출력 가능하다.
NULL은 정상적인 산술 연산이 불가능하기 때문에 ‘=’과 ‘!=’을 사용할 수 없다.
문제1: A: TB_CUST 테이블에서 PHONE_NO가 (null)인 데이터를 출력해주세요.
1
2
3
SELECT *
FROM TB_CUST
WHERE PHONE_NO IS NULL;
SQL 연산자
IN
SQL연산자로는 IN, BETWEEN, LIKE가 있는데, 이중 IN 연산자는 OR연산자의 중복 사용을 간단하게 해주는 연산자이다.
가령, 다음과 같은 상황이 있다고 가정해보자:
Q: TB_PRD 테이블에서 PRD_TYPE이 가전이거나, 욕실용품이거나, 스마트폰인 대상의 모든 정보를 출력해주세요.
IN 연산자를 사용하지 않는다면 다음과 같이 작성을 해야 할 것이다.
1
2
3
4
5
SELECT *
FROM TB_PRD
WHERE PRD_TYPE = '가전'
OR PRD_TYPE = '욕실용품'
OR PRD_TYPE = '스마트폰';
IN 연산자를 사용하게 되면 아래와 같이 한 줄에 작성할 수 있다.
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_TYPE IN('가전', '욕실용품', '스마트폰');
BETWEEN
BETWEEN 연산자는 범위조건 연산이다.
Q: TB_CUST 테이블에서 ACT_POINT가 100 이상이면서 1000 이하인 값을 가진 대상의 모든 정보를 출력해주세요.
1
2
3
4
SELECT *
FROM TB_CUST
WHERE ACT_POINT >= 100
AND ACT_POINT <= 1000;
위의 문을 BETWEEN을 사용하여 아래와 같이 다시 작성할 수 있다.
1
2
3
SELECT *
FROM TB_CUST
WHERE ACT_POINT BETWEEN(100 AND 1000);
주의해야 하는 점이, BETWEEN은 무조건 A이상 B이하 조건이다. 즉, >=, <= 라는 것이기 떄문에 A와 B값 또한 범위에 포함된다.
LIKE
LIKE연산은 매칭 연산을 할 수 있다.
매칭 연산 = 특정 키워드를 포함한 항목을 찾는 것
LIKE 연산자는 _ 또는 % 같은 와일드카드를 이용해 매칭 연산을 수행한다.
문제1: TB_PRD 테이블에서 PRD_NAME이 ‘수’로 시작하는 모든 정보를 출력해주세요.
A:
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_NAME LIKE '수%'
문제2: TB_PRD 테이블에서 PRD_NAME에 ‘용’이 포함되는 모든 정보를 출력해주세요.
A:
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_NAME LIKE '%용%'
문제3: TB_PRD 테이블에서 PRD_NAME이 ‘기’로 끝나는 모든 정보를 출력해주세요.
A:
1
2
3
SELECT *
FROM TB_PRD
WHERE PRD_NAME LIKE '%기'
%는 0개 이상의 문자를 매칭해준다.
_는 1개의 문자를 매칭해준다.