관계형 데이터베이스
- RDB(Relational Database)라고 불리는 관계형 데이터베이는 말 그대로 관계형 데이터 모델에 기초를 둔 데이터베이스이다.
- 관계형 데이터베이스의 설계는 모든 데이터를 2차원 테이블 형태로 표현한 뒤 각 테이블 간의 관계를 정의하는 것으로 시작된다.
- RDBMS(Relational Database Management System)는 이러한 RDB를 관리 감독하기 위한 시스템이다.
- Ex. Oracle, SQL Server(MSSQL), MySQL, MariaDB, PostgreSQL 등
Table
- 관계형 데이터베이스를 표현할때 사용하는 형식이다.(엑셀 표 형식과 유사)
- 항목을 나타내는 각각의 세로 열을 칼럼(Column)이라고 한다.
- 각각의 가로 행을 로우(Row)라고 한다.
- 테이블은 관계형 데이터베이스의 기본 단위이고 일반적으로 데이터베이스는 여러 개의 테이블로 구성된다.
- 데이터를 저장하는 주된 목적은 데이터를 활용하는 데에 있고 우리는 그것을 테이블 형태로 조회하고 변경하고 삭제할 수 있다.
게임 |
유저명 |
플레이타임(시간) |
메이플 |
닉네임메 |
10 |
롤 |
닉네임롤 |
20 |
SQL(Structured Query Language)
- SQL은 관계형 데이터베이스에서 데이터를 다루기 위해 사용하는 언어이다.
- 간단한 SQL 작성 방법은 뻔하기에 누가 작성하든 비슷하지만 라인 수가 많아지는 복잡한 SQL은 어떻게 작성하냐에 따라 성능 차가 확연하기에 SQL을 잘 작성하고 튜닝하는 것이 중요하다.
SELECT
- 저장되어 있는 데이터를 조회하고자 할 때 사용하는 명령어이다.
SELECT 컬럼1, 컬럼2, ... FROM 테이블 WHERE 컬럼1 = '아무개';
- 컬럼을 따로 명시하지 않고 *(asterisk)를 쓰면 전체 컬럼이 조회되며 조회되는 컬럼의 순서는 테이블 컬럼 순서와 동일하다.
SELECT * FROM 테이블;
- 별도의 WHERE 절이 없으면 테이블 전체 Row가 조회된다.
SELECT BAND.BAND_NAME, BAND_MEMBER.MEMBER_NAME
FROM BAND, BAND_MEMBER
WHERE BAND.BAND_CODE = BAND_MEMBER.BAND_CODE;
↓
SELECT B.BAND_NAME, BM.MEMBER_NAME
FROM BAND B, BAND_MEMBER BM
WHERE B.BAND_CODE = BM.BAND_CODE;
- 테이블이나 컬럼 명에 별도의 별칭을(Alias)을 붙여줄 수 있는데, 붙여주는 목적은 줄여쓰기 위함이다.
- FROM절에서 정의한다.
- 테이블명에 Alias를 설정했을 경우 테이블명 대신 Alisa를 사용해야 한다. 아닐 경우 문법 에러가 발생한다.
산술 연산자
- 수학에서 사용하는 사칙연산의 기능을 가진 연산자이다.
- NULL이 포함된 연산을 주의하자
- 다른 컬럼끼리 연산(가로 연산)에서 NULL이 포함되어 있으면 결과 값은 NULL이다
- 다른 로우끼리 연산(세로 연산)에서 NULL이 포함되어 있으면 결과 값은 NULL을 제외하고 연산한 결과이다.
연산자 |
의미 |
우선순위 |
() |
우선순위 조정 |
1 |
* |
곱하기 |
2 |
/ |
나누기 |
+ |
더하기 |
3 |
- |
빼기 |
합성 연산자
- 문자와 문자를 연결할 때 사용하는 연산자이다.
SELECT 'S'||'Q'||'L'||'개'||'발'||'자' AS SQLD FROM DUAL
↓
함수
- 데이터베이스에서 매핑을 제공하는 함수들이 있다.
- 문자 함수
- CHR(ASCII 코드)
- ASCII 코드는 총 128개의 문자를 숫자로 표현할 수 있도록 정의해 놓은 코드이다.
- ASCII 코드를 인수로 입력하였을때 매핑되는 문자가 무엇인지를 알려주는 함수이다.
- Ex. CHR(65) → A
- LOWER(문자열)
- 문자열을 소문자로 변환해주는 함수이다.
- Ex. LOWER('KIM') → kim
- UPPER(문자열)
- LTRIM(문자열 [,특정 문자]) *[]는 옵션
- 특정 문자를 따로 명시해주지 않으면 문자열의 왼쪽 공백을 제거한다.
- 특정 문자를 명시한 경우 문자열을 왼쪽부터 한 글자씩 특정 문자와 비교하여 특정 문자에 포함되어 있으면 제거하고 포함되지 않았으면 멈춘다.
- 문자 사이의 공백은 제거하지 않는다.
- SQL Server(MSSQL)의 경우 공백 제거만 가능하다.
- Ex. LTRIM(' KIM') → KIM
- Ex. LTRIM('DATABASE', 'DE') → ATABASE
- RTLIM(문자열 [,특정 문자]) *[]는 옵션
- LTRIM과 방향만 반대이고 같은 기능을 가진다.
- TRIM([위치] [특정 문자] [FROM] 문자열) *[]는 옵션
- 옵션이 없는 경우 문자열 양쪽의 공백을 제거한다.
- 옵션이 있는 경우 옵션에 따라 지정된 위치에서 한 글자씩 특정 문자와 비교하여 제거하고 다르면 멈춘다.
- SQL Server(MSSQL)의 경우 공백 제거만 가능하다.
- Ex. TRIM(' KIM ') → KIM
- Ex. TRIM(LEADING 'K' FROM 'KIM') → IM
- Ex. TRIM(TRALLING 'M' FROM 'KIM') → KI
- SUBSTR(문자열, 시작점 [,길이]) *[]는 옵션
- 문자열의 원하는 부분만 잘라서 반환해주는 함수이다.
- 길이를 명시하지 않은 경우 문자열의 시작부터 끝까지 반환된다.
- 길이 옵션보다 문자열이 짧은 경우 문자열의 끝까지 반환된다.
- Ex. SUBSTR('교촌치킨허니콤보', 3, 2) → 치킨
- Ex. SUBSTR('교촌치킨허니콤보', 5, 4) → 허니콤보
- LENGTH(문자열)
- 문자열의 길이를 반환해주는 함수이다.
- Ex. LENGTH('교촌치킨허니콤보') → 8
- REPLACE(문자열, 변경 전 문자열 [변경 후 문자열]) *[]는 옵션
- 문자열에서 변경 전 문자열을 찾아 변경 후 문자열로 바꿔주는 함수이다. 변경 후 문자열을 명시해 주지 않으면 문자열에서 변경 전 문자열을 제거한다.
- Ex. REPLACE('교촌치킨허니콤보', '허니', '꿀') → 교촌치킨꿀콤보
- Ex. SELECT REPLACE('교촌치킨허니콤보', '허니') → 교촌치킨콤보
- 숫자 함수
- ABS(수)
- 수의 절대값을 반환해주는 함수이다.
- SIGN(수)
- 수의 부호를 반환해주는 함수이다. 양수이면 1, 음수이면 -1, 0이면 0을 반환한다
- Ex. SIGN(-7) → 1
- ROUND(수, [,자릿수]) *[]는 옵션
- 수를 지정된 소수점 자릿수까지 반올림하여 반환해주는 함수이다.
- 자릿수를 명시하지 않으면 기본값은 0이며 반올림된 정수로 반환한다.
- 자릿수가 음수인 경우 지정된 정수브를 반올림하여 반환한다.
- Ex. ROUND(178.356, 1) → 178.4
- Ex. ROUND(178.356, -2) → 200
- TRUNC(수 [,자릿수])
- 수를 지정된 소수점 자릿수까지 버림하여 반환해주는 함수이다.
- 자릿수를 명시하지 않았을 경우 기본 값을 0이며 버림된 정수를 반환한다.
- 자릿수가 음수인 경우 지정된 정수부에서 버림하여 반환한다.
- Ex. TRUNC(55.62, 1) → 55.6
- Ex. TRUNC(55.62, -1) → 50
- CELL(수)
- 소수점 이하의 수를 올림한 정수를 반환해주는 함수이다.
- SQL Server(MSSQL)의 경우 CELING(문자열)
- Ex. CELL(72.86) → 73
- Ex. CELL(-33.4) → 33
- FLOOR(수)
- 소수점 이하의 수를 버림한 정수를 반환해주는 함수이다.
- 음수에서는 '버림'이 아닌 '내림'임에 주의하자
- Ex. FLOOR(22.3) → 22
- Ex. FLOOR(-22.3) → -23
- MOD(수1, 수2)
- 수1을 수2로 나눈 나머지를 반환해주는 함수이다.
- MOD 함수의 두 번째 인자값이 0이면 첫 번째 인자 값이 결과로 도출된다.
- MOD 함수의 두 인자값이 모두 음수이면 나머지도 그대로 음수값으로 도출된다.
- Ex. MOD(15, 7) → 1
- Ex. MOD(15, -4) → 3
- 날짜 함수
- SYSDATE
- 현재의 연, 월, 일, 시, 분, 초를 반환해주는 함수이다.
- nls_data_format에 따라서 sysdate의 출력 양식은 달라질 수 있다.
- SQL Server(MSSQL)의 경우 GETDATE()
- Ex. SYSDATE → 2022-08-31 20:12:56
- EXTRACT(특정 단위 FROM 날짜 데이터)
- 날짜 데이터에서 특정 단위(YEAR, MONTH, DAY HOUR, MINUTE, SECOND)만을 출력해서 반환해주는 함수이다,
- Ex. EXTRACT(YEAR FROM SYSDATE) → 2022
- Ex. EXTRACT(MONTH FROM SYSDATE) → 8
- Ex. EXTRACT(DAY FROM SYSDATE) → 31
- ADD_MONTH(날짜 데이터, 특정 개월 수)
- 날짜 데이터에서 특정 개월 수를 더한 날짜를 반환해주는 함수이다.
- 날짜의 이전 달이나 다음 달에 기준 날짜의 일자가 존재하지 않으면 해당 월의 마지막 일자가 반환된다.
- SQL Server(MSSQL)의 경우 DATEADD(MONTH, 특정 개월 수, 날짜 데이터)
- Ex. ADD_MONTH(TO_DATE('2022-08-31', 'YYYY-MM-DD'), -1) → 2022-09-30
- 반환 함수
- 명시적 형변환과 함시적 형변환
- 데이터베이스에서 데이터 유형에 대한 형변환을 할 수 있는 방법은 두 가지가 있다.
- 명시적 형변환: 변환 함수를 사용하여 데이터 유형 변환을 명시적으로 나타냄
- 암시적 형변환: 데이터베이스가 내부적으로 알아서 데이터 유형을 변환함
- Ex. VARCHAR 유형의 BIRTHDAY 컬럼을 숫자와 비교할 경우, 데이터 베이스는 오류를 뱉지 않고 내부적으로 BIRTHDAY 컬럼을 NUMBER형으로 변환하게 되는데 이럴 때 쓰이는 것이 암시적 형변환이다.
- 암시적 형변환이 가능하다고해서 데이터 유형을 고려하기 않고 SQL 작성을 하는 것은 성능 저하를 유발한다.
- 따라서 되도록 명시적 형변환을 사용하는 것이 좋다.
- 명시적 형변환에 쓰이는 함수
- SQL Server(MSSQL)의 경우 CONVERT나 CAST 함수를 사용할 수 있다.
- TO_NUMBER(문자열)
- 문자열을 숫자형으로 변환해주는 함수이다.
- Ex. TO_NUMBER('1234') → 1234
- Ex. TO_NUMBER('abc') → Error 발생!
- TO_CHAR(수 or 날짜 [, 포맷]) * []는 옵션
- 수나 날짜형의 데이터를 포맷 형식의 문자형으로 변환해주는 함수이다.
- Ex. TO_CHAR(1234) → '1234'
- Ex. TO_CHAR(SYSDATE, 'YYYYMMDD HH24MISS') → 20220831 203309
- TO_DATE(문자열, 포맷)
- 포맷 형식의 문자형의 데이터를 날짜형으로 변환해주는 함수이다.
- Ex. TO_DATE('20220831', 'YYYYMMDD') → '2022-08-31'
포맷 표현 |
의미 |
포맷표현 |
의미 |
YYYY |
년 |
HH |
시(12) |
MM |
월 |
HH24 |
시(24) |
DD |
일 |
MI |
분 |
|
|
SS |
초 |
- NULL 관련 함수
- NVL(인수1, 인수2)
- 인수 1의 값이 NULL일 경우 인수2를 반환하고 NULL이 아닐 경우 인수1을 반환해주는 함수이다.
- SQL Server(MMSQL)의 경우 ISNULL(인수1, 인수2)
- Ex. NVL(REVIEW_SCORE, 0)
- REVIEW_SCORE가 NULL인 경우 0를 반환
- NULL이 아닌 경우 REVIEW_SCORE를 반환
- NULLIF(인수1, 인수2)
- 인수1과 인수2가 같으면 NULL을 반환한다.
- 인수1과 인수2가 같지 않으면 인수1을 반환한다.
- Ex. NULLIF(5, 5) → NULL
- Ex. NULLIF(5, 3) → 5
- COALESCE(인수1, 인수2, 인수3...)
- NULL이 아닌 최초의 인수를 반환해주는 함수이다.
- Ex. COALESCE(NULL, NULL, '000-000-000', '000@SQLD.COM', 5, NULL) → '000-000-000'
- CASE
- CASE는 함수와 성격이 같기는 하지만 표현방식이 함수라기보다는 구문에 가깝다고 할 수 있다.
- 문장으로는 '~이면 ~이고', '~이면 ~이다' 식으로 표현되는 구문이다.
- 필요에 따라 각 CASE를 여러 개로 늘릴 수도 있다.
- 같은 기능을 하는 함수로는 Oracle의 DECODE 함수가 있다.
- *[]는 옵션
- 다음 구문은 같은 결과를 반환한다.
CASE WHEN SUBWAY_LINE='1' THEN 'BLUE'
WHEN SUBWAY_LINE='2' THEN 'GREEN'
WHEN SUBWAY_LINE='3' THEN 'ORANGE'
[ELSE 'GRAY']
END
CASE SUBWAY_LINE
WHEN '1' THEN 'BLUE'
WHEN '2' THEN 'GREEN'
WHEN '3' THEN 'ORANGE'
[ELSE 'GRAY']
END
DECODE (SUBWAY_LINE,'1','BLUE','2','GREEN','3','ORANGE'[,GRAY])
WHERE 절
- INSERT를 제외한 DML문을 수행할 때 원하는 데이터만 골라 수행할 수 있도록 해주는 구문이다.
- 예를들면 NAME 컬럼이 '이지은'인 컬럼만 SELECT 할 수도 있고 '이지은'이 아닌 컬럼만 SELECT 할 수도 있다.
- UPDATE나 DELETE도 마찬가지이다.
- WHERE 절의 위치는 다음과 같다.
- Ex. SELECT 컬럼1, 컬럼2 ... FROM 테이블 WHERE 조건절;
- Ex. UPDATE 테이블명 SET 컬럼명 = 새로운 데이터 WHERE 조건절;
- Ex. DELETE FROM 테이블 WHERE 조건절;
- 다양한 WHERE 절에 대하여 알아보자.
비교 연산자
비교 연산자 |
의미 |
예시 |
= |
같음 |
where col = 10 |
< |
작음 |
where col < 10 |
<= |
작거나 같음 |
where col <= 10 |
> |
큼 |
where col > 10 |
>= |
크거나 같음 |
where col >= 10 |
# 다음 쿼리는 CITY가 Paris인 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, CITY
FROM MEMBER
WHERE CITY = 'Paris';
# 다음 쿼리는 MEMBER_NO가 10보다 작은 행을 조회한다.
SELECT MEMBER_NO, FIRST_NAEM, LAST_NAME
FROM MEMBER
WHERE MEMBER_NO < 10;
# 다음 쿼리는 FIRST_NAME과 Mark의 데이터 타입이 맞지 않아 에러가 발생한다.
SELECT FIRST_NAME, LAST_NAME, EMAIL
FROM MEMBER
WHER FIRST_NAME = Mark;
# FIRST_NAME과 같은 문자형 컬럼을 비교 조건으로 사용하려면 우측 상수값을 반드시 인용부호로 감싸야한다.
부정 비교 연산자
부정 비교 연산자 |
의미 |
예시 |
!= |
같지 않음 |
where col1 != 10 |
^= |
같지 않음 |
where col1 ^= 10 |
<> |
같지 않음 |
where col1 <> 10 |
not 컬럼명 = |
같지 않음 |
where not col1 = 10 |
not 컬럼명 > |
크지 않음 |
where not col1 > 10 |
# 다음 쿼리는 FAVORITES이 Y가 아닌 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE FAVORITES <> 'Y';
SQL 연산자
SQL 연산자 |
의미 |
예시 |
BETWEEN A AND B |
A와 B 사이(A, B 포함) |
where col between 1 and 10 |
LIKE '비교 문자열' |
비교 문자열을 포함 |
where col like '방탄%' where col like '%소년단' where col like '%탄소년%' where col like '방_소%' |
IN (LIST) |
LIST 중 하나와 일치 |
where col in (1, 3, 5) |
IS NULL |
NULL 값 |
where col is null |
# 다음 쿼리는 PLAY_ID가 1 이상, 5이하인 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE PLAY_ID BETWEEN 1 AND 5;
# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE PLAY_ID >= 1 AND PLAY_ID <=5;
# 다음 쿼리는 NAME이 Classical로 시작되는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NAME LIKE 'Classical%';
# 다음 쿼리는 NAME이 Music으로 끝나는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NAME LIKE '%Music';
# 다음 쿼리는 NAME이 M으로 시작하고 S로 끝나는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NAME LIKE 'M&S';
# 다음 쿼리는 NAMEDP 101이 포함된 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NAME LIKE '&101%';
# 다음 쿼리는 TITLE이 IT Staff이거나 IT Manager인 행을 조회한다.
SELECT LAST_NAME, FIRST_NAEM, TITLE
FROM EMPLOYEE
WHERE TITLE IN ('IT Staff', 'IT Manager');
# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE (TITLE = 'IT Staff' OR TITLE = 'IT Manager');
# 다음 쿼리는 COMPANY가 NULL인 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, COMPANY
FROM MEMBER
WHERE COMPANY IS NULL;
부정 SQL 연산자
부정 SQL 연산자 |
의미 |
예시 |
NOT BETWEEN A AND B |
A와 B의 사이가 아님(A, B 미포함) |
where col not between 1 and 10 |
NOT IN (LIST) |
LIST 중 일치하는 것이 없음 |
where col not in (1, 3, 5) |
IS NOT NULL |
NULL 값이 아님 |
where col is not null |
# 다음 쿼리는 PLAY_ID가 1이상, 5이하가 아닌 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE PLAY_ID NOT BETWEEN 1 AND 5;
# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NOT (PLAY_ID BTWEEN 1 AND 5);
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NOT (PLAY_ID >= 1 AND PLAY_ID <= 5);
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE PLAY_ID < 1 OR PLAY_ID > 5;
# 다음 쿼리는 TITLE이 IT Staff와 IT Manager가 아닌 행을 조회한다.
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE TITLE NOT IN ('IT Staff', 'IT Manager');
# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE NOT (TITLE IN ('IT Staff', 'IT Manager'));
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE NOT (TITLE = 'IT Staff' OR TITLE = 'IT Manager');
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE TITLE <> 'IT Staff' AND TITLE <> 'IT Manager';
# 다음 쿼리는 COMPANY가 NULL이 아닌 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, COMPANY
FROM MEMBER
WHERE COMPANY IS NOT NULL;
논리 연산자
- 논리 연산자에는 처리 순서가 존재하는데 SQL에 명시된 순서와는 관계없다.
- () → NOT → AND → OR 순으로 처리된다.
논리 연산자 |
의미 |
예시 |
NOT |
TRUE이면 FALSE이고 FALSE이면 TRUE |
where not col > 10 |
AND |
모든 조건이 TRUE여야 함 |
where col>1 and col<10 |
OR |
하나 이상의 조건이 TRUE여야 함 |
where col=1 or col=10 |
GROUP BY, HAVING 절
- GROUP BY
- GROUP BY는 말 그대로 데이터를 그룹별로 묶을 수 있도록 해주는 절이다.
- GROUP 뒤에 수단의 전치사인 BY가 붙었기 때문에 GROUP BY 뒤에는 그룹핑의 기준이 되는 컬럼이 온다.
- 컬럼은 하나또는 그 이상이 될 수 있다.
- 집계 함수
- 데이터를 그룹별로 나누면 그룹별로 집계 데이터를 도출하는 것이 가능해진다.
COUNT(*) |
전체 Row를 Count하여 반환 |
COUNT(컬럼) |
컬럼값이 Null인 Row를 제외하고 Count하여 반환 |
COUNT(DISTINCT 컬럼) |
컬럼값이 Null이 아닌 Row에서 중복을 제거한 Count를 반환 |
SUM(컬럼) |
컬럼값들의 합계 반환 |
AVG(컬럼) |
컬럼값들의 평균 반환 |
MIN(컬럼) |
컬럼값들의 최솟값 반환 |
MAX(컬럼) |
컬럼값들의 최댓값 반환 |
- HAVING
- HAVING 절은 GROUP BY 절을 사용할 때 WHERE 절처럼 사용하는 조건절이라고 생각하면된다.
- 주로 데이터를 그룹핑한 후 특정 그룹을 골라낼 때 사용한다.
- HAVING 절은 논리적으로 GROUP BY 절 이후에 수행되기에 그룹핑 후에 가능한 집계 함수로 조건을 부여할 수 있다.
- HAVING 절은 논리적으로 SELECT 절 전에 수행되기에 SELECT 절에 명시되지 않은 집계 함수로도 조건을 부여하는 것이 가능하다.
- 주의할 점은 WHERE 절을 사용해도 되는 조건까지 HAVING 절로 써버리면 성능상 불리할 수 있다는 점이다.
- WHERE 절에서 필터링을 선행해야 GROUP BY 할 데이터량이 줄어들어 성능에 유리하다.
SELECT 문의 논리적 수행 순서
SELECT → 5 FROM → 1 WHERE → 2 GROUP BY → 3 HAVING → 4 ORDER BY → 6 |
ORDER BY 절
- ORDER BY
- ORDER BY 절은 SELECT 문에서 논리적으로 맨 마지막에 수행된다.
- ORDER BY 절을 사용하여 SELECT한 데이터를 정렬할 수 있다.
- ORDER BY 절을 따로 명시하지 않으면 데이터는 임의의 순서대로 출력된다.
- ORDER BY 절 뒤에는 정렬의 기준이 되는 컬럼이 오게된다.
- 기준이 되는 컬럼은 하나 또는 그 이상이 될 수도 있다.
- ORDER BY 절 뒤에 오는 컬럼에는 옵션이 붙을 수 있으며 종류는 다음과 같다.
- ASC(Ascending) : 오름차순
- DESC(Descending) : 내림차순
- 옵션 생략 시 ASC가 기본값이 된다.
- 정렬의 기준이 되는 컬럼에 NULL 데이터가 포함되어 있는 경우 데이터베이스 종류에 따라 정렬의 위치가 달라진다.
- Oracle의 경우에는 NULL을 최댓값으로 취급하기 때문에 오름차순을 했을 경우 맨 마지막에 위치한다.(SQL Server는 반대)
- 만약 순서를 변경하고 싶다면 ORDER BY 절에 NULLS FIRST, NULLS LAST 옵션을 써서 NULL의 정렬상 순서를 변경할 수 있다.
JOIN
- JOIN이란?
- 테이터베이스에서 조인이란 각기 다른 테이블을 한 번에 보여줄 때 쓰는 쿼리이다.
- 실무에서 SQL을 작성할 때 8할이 JOIN 쿼리라고 얘기해도 무방하다.
- JOIN되는 두 테이블에 모두 존재하는 컬럼의 경우 컬럼명 앞에 반드시 테이블명이나 ALIAS를 명시해주어야 함
- EQUI JOIN
- EQUI JOIN은 Equal(=) 조건으로 JOIN하는 것으로 가장 흔히 볼 수 있는 JOIN의 방식이라고 할 수 있다
SELECT A.PRODUCT_CODE,
A.PRODUCT_NAME,
B.MEMBER_ID,
B.CONTENT,
B.REG_DATE
FROM PRODUCT A,
PRODUCT_REVIEW B
WHERE A.PRODUCT_CODE = B.PRODUCT_CODE
AND A.PRODUCT_CODE = '100001';
- Non EQUI JOIN
- Non EQUI JOIN은 Equal(=) 조건이 아닌 다른 조건(BETWEEN, >, >=, <, <=)으로 JOIN 하는 방식이다.
- 예를 들어 이벤트 기간 동안 리뷰를 작성한 고객에게 사은품을 주는 행사를 하고 있다고 가정해보자.
- 이 경우 리뷰 테이블과 이벤트 테이블이 JOIN되어야 할 것이다.
SELECT A.EVENT_NAME,
B.MEMBER_NAME,
B.CONTENT,
B.REG_DATE
FROM EVENT A,
PRODUCT_REVIEW B
WHERE B.REG_DATE BETWEEN A.START_DATE AND A.END_DATE;
- OUTER JOIN
- OUTER JOIN은 앞서 본 JOIN과는 다르게 JOIN 조건에 만족하지 않는 행들도 출력되는 형태이다.
- LEFT OUTER JOIN의 경우 LEFT TABLE과 RIGHR TABLE의 데이터 중 JOIN에 성곤한 데이터와 그렇지 못한 나머지 LEFT TABLE의 데이터가 함께 출력된다.
- Oracle에서는 모든 행이 출력되는 테이블의 반대편 테이블의 옆에(+) 기로를 붙여 작성해주면 된다.
# LEFT OUTER JOIN이다.
SELECT A.PRODUCT_CODE,
A.PRODUCT_NAME,
B.MEMBER_ID,
B.CONTENT,
B.REG_DATE
FROM PRODUCT A,
PRODUCT_REVIEW B
WHERE A.PRODUCT_CODE = B.PRODUCT_CODE(+);
STANDARD JOIN
- DBMS가 여러개가 존재하는데 호환성 이슈가 발생하여 하나의 표준을 정한것이다.
- ANSI SQL, 표준 조인이라는 말을 많이 사용한다.
- INNER JOIN
- JOIN 조건에 충족하는 데이터만 출력되는 방식이다.
- 앞서 본 SQL과의 차이점은 JOIN 조건을 ON 절을 사용하여 작성해야 한다는 점이다.
SELECT A.PRODUCT_CODE,
A.PRODUCT_NAME,
B.MEMBER_ID,
B.CONTENT,
B.REG_DATE
FROM PRODUCT A INNER JOIN PRODUCT REVIEW B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;
- OUTER JOIN
- JOIN 조건에 충족하는 데이터가 아니어도 출력될 수 있는 방식이다.
- LEFT OUTER JOIN
- SQL에서 왼쪽에 표기된 테이블의 데이터는 무조건 출력되는 JOIN이다.
- 오른쪽 테이블에 JOIN되는 데이터가 없는 ROW들은 오른쪽 테이블 컬럼의 값이 NULL로 출력된다.
- RIGHT OUTER JOIN
- SQL에서 오른쪽에 표기된테이블의 데이터는 무조건 출력되는 방식이다.
- 왼족 테이블에 JOIN되는 데이터가 없는 ROW들은 왼쪽 테이블 컬럼의 값이 NULL로 출력된다.
- FULL OUTER JOIN
- 왼쪽, 오룬쪽 테이블의 데이터가 모두 출력되는 방식이다.
- LEFT OUTER JOIN과 RIGHT OUTER JOIN의 합집합이라고 이해하면 쉽다.(단 중복값은 제거)
- NATURAL JOIN
- A 테이블과 B 테이블에서 같은 이름을 가진 컬럼들이 모두 동일한 데이터를 가지고 있을 경우 JOIN이 되는 방식이다.
- SQL Server(MSSQL)에서는 지원하지 않는다.
- Oracle의 경우 USING 조건절을 사용하여 같은 이름을 가진 컬럼중 원하는 컬럼만 JOIN에 사용할 수도 있다.
- 단, SELECT 절에서 USING 절로 정의된 컬럼 앞에는 별도의 ALIAS나 테이블명을 붙이지 않아야 한다.
- CROSS JOIN
- 예선 수학 시간에 경우의 수에 대해 배운 적이 있을 것이다.
- 비슷한 맥락으로 CROSS JOIN은 A 테이블과 B 테이블 사이에 JOIN 조건이 없는 경우, 조합할 수 있는 모든 경우를 출력하는 방식이다.
- 다른 말로 Cartesian Product라고 표현하기도 한다.
문제 풀이중 팁
- NULL과의 연산 결과는 False이므로 조건값이 늘 거짓이 되어 아무 데이터도 출력되지 않는다.
- CASE 문에서 ELSE 뒤의 값이 DEFAULT 값이 되고 별도의 ELSE가 없을 경우 NULL 값이 DEFAULT 값이 된다.
- 나누기 연산을 할때 0으로 나누려하면 에러가 발생한다.
- NATURAL JOIN은 공통 컬럼 앞에 OWNER 명을 붙이면 에러가 발생한다.
- ALIAS를 별도로 지정해주지 않으면 컬럼명이 대문자로 출력된다.
- ORDER BY 절에는 컬럼명을 명시해줄 수도 있고 SELECT 절에 기술된 컬럼의 순서를 숫자로 명시해줄 수도 있다.
- AVG, MAX 함수는 각각 NULL 값을 제외하고 계산된다.
- HAVING 절은 주로 GROUP BY 절 뒤에 오면서 집계 데이터에 대한 조건을 부여하지만 테이블 전체가 한 개의 그룹이 되는 경우 HAVING만 단독으로 사용할 수 있다.