SQL 기본
- -
본 게시물은 ‘정미나, ⌜2022 유선배 SQL개발자(SQLD)⌟, 시대고시기획, 2022’ 을 인용하였습니다.
1. 관계형 데이터베이스 개요
1-1. 데이터베이스
- 데이터들을 저장하는 공간
- 용도와 목적에 맞는 데이터들끼리 모아서 저장
1-2. 관계형 데이터베이스(RDB(Relational Database))
- 관계형 데이터 모델에 기초를 둔 데이터 베이스
- RDB 설계는 모든 데이터를 2차원 테이블 형태로 표현한 뒤 각 테이블 관계를 정의하는 것부터 시작
- RDBMS(Relational Database Management System)는 RDB를 관리/감독하기 위한 시스템
- Oracle, SQL Server(MSSQL), MySQL, MariaDB, PostgreSQL 등이 속함
1-3. TABLE
- 가족에 대한 데이터를 테이블로 만들기
- 가족 구성원을 떠올린 후 그들의 데이터를 같은 항목끼리 묶기

- 항목을 나타내는 세로 열(관계, 이름, 생년월일, 직업, 취미, 좋아하는 음식)을 컬럼(Column)이라고 함
각 가로 행을 로우(Row)라고 함 - 시간이 지나 김달의 직업 컬럼이 업데이트 될 것이고, 신규 로우가 추가될 수 있음

- 테이블은 관계형 데이터베이스의 기본 단위이며 일반적으로 데이터베이스는 여러 개의 테이블로 구성됨
- 데이터 저장의 주된 목적은 데이터를 활용하는데 있고 테이블 형태로 조회/변경/삭제할 수 있음
1-4. SQL(Structured Query Language)
- SQL : 관계형 데이터베이스에서 데이터를 다루기 위해 사용하는 언어
- 데이터베이스가 이해할 수 있는 언어인 SQL을 사용해 명령어 실행시켜 컬럼 등 업데이트O
2. SELECT문
2-1. SELECT
저장되어 있는 데이터를 조회하고자 할 때 사용하는 명령어
- SELECT문
SELECT 컬럼1, 컬럼2, ... FROM 테이블 WHERE 컬럼1 = '아무개';
- SELECT문 * 사용
- *(asterisk) : 전체 컬럼이 조회됨
- 조회되는 컬럼 순서는 테이블 컬럼 순서와 동일
- 별도의 WHERE 절이 없으면, 테이블 전체 Row가 조회됨
SELECT * FROM 테이블;
- 별칭(Alias) : 짧게 줄여 쓰기 위함
SELECT BAND.BAND_NAME, BAND_MEMBER.MEMBER_NAME
FROM BAND, BAND_MEMBER
WHERE BAND.BAND_CORE = BAND_MEMBER.BAND_CODE;
↓
SELECT B.BAND_NAME, BM.MEMBER_NAME
FROM BAND B, BAND_MEMBER BM
WHERE B.BAND_CODE = BM.BAND_CODE;
2-2. 산술 연산자
수학에서 사용하는 사칙연산 기능 가진 연산자

SELECT COL1+COL2 AS A,
COL1-COL2 AS S,
COL1*COL2 AS M,
COL1/COL2 AS D
FROM SAMPLE;
- 연산에서 NULL이 포함되어 있으면, 결과값은 NULL이 됨
2-3. 합성 연산자
문자와 문자를 연결할 때 사용하는 연산자
- 합성연산자 예시
SELECT 'S'||'Q'||'L'||'개'||'발'||'자' AS SQLD
FROM DUAL;

- 합성 연산자 예시
SELECT * FROM SAMPLE;

SELECT COL1 || ' ' || 'SQLD' || ' ' || COL2 AS RESULT
FROM SAMPLE;

3. 함수
3-1. 문자 함수
1. CHR(ASCII 코드)
- ASCII 코드 : 128개 문자를 숫자로 표현할 수 있도록 정의한 코드
- CHR 함수 : ASCII 코드를 인수로 입력했을 때 매핑되는 문자가 무엇인지 알려주는 함수
- cf. SQL Server(MSSQL) 경우, CHAR(ASCII 코드)
- 예시(CHR(65) : A)
SELECT CHR(65) FROM DUAL;

2. LOWER(문자열)
- 문자열을 소문자로 변환해주는 함수
- 예시
SELECT LOWER('JENNIE') FROM DUAL;

3. UPPER(문자열)
- 문자열을 대문자로 변환해주는 함수
- 예시
SELECT UPPDER('JENNIE') FROM DUAL;

4. LTRIM(문자열 [, 특정 문자]) *[ ]는 옵션
- 특정 문자 명시X -> 문자열 왼쪽 공백 제거
- 특정 문자 명시O -> 문자열 왼쪽부터 한 글자씩 특정 문자와 비교해 특정 문자에 포함되면 제거, 포함X라면 멈춤
- cf. SQL Server(MSSQL) 경우, 공백 제거만O
- 특정 문자 명시X 경우 LTRIM : 왼쪽 공백부터 제거
SELECT LTRIM(' JENNIE') FROM DUAL;

- 특정 문자 명시O 경우 LTRIM : 왼쪽부터 비교해 포함하면 제거, 포함X라면 멈춤
SELECT LTRIM('블랙핑크', '블랙') FROM DUAL;

5. RTRIM(문자열 [, 특정 문자]) * []는 옵션
- 특정 문자 명시X -> 문자열 오른쪽 공백 제거
- 특정 문자 명시O -> 문자열 오른쪽부터 한 글자씩 특정 문자와 비교해 특정 문자에 포함되면 제거, 포함X라면 멈춤
- cf. SQL Server(MSSQL) 경우, 공백 제거만O
- 특정 문자 명시X 경우 RTRIM : 오른쪽 공백 제거
SELECT RTRIM('JENNIE ') FROM DUAL;

- 특정 문자 명시O 경우 RTRIM : 오른쪽부터 특정 문자에 포함되면 제거, 포함X라면 멈춤
SELECT RTRIM('블랙핑크', '핑크') FROM DUAL;

6. TRIM([위치] [특정 문자] [FROM] 문자열) * []는 옵션
- 옵션 無, 문자 왼쪽/오른쪽 공백 제거
- 옵션 有, 문자열 위치(LEADING or TRALING or BOTH)로 지정된 곳부터 한 글자씩 특정 문자와 비교해 같으면 제거, 다르면 멈춤
- LTRIM, RTRIM과 달리 특정 문자는 한 글자만 지정O
- cf. SQL Server(MSSQL) 경우, 공백 제거만O
- 옵션X 경우 TRIM : 문자 왼쪽/오른쪽 공백 제거
SELECT TRIM(' JENNIE ') FROM DUAL;

- 옵션O 경우 TRIM : 문자열 위치 지정된 곳부터 비교해 같으면 제거, 다르면 멈춤
SELECT TRIM(LEADING '블' FROM '블랙핑크') FROM DUAL;

SELECT TRIM(TRAILING '크' FROM '블랙핑크') FROM DUAL;

7. SUBSTR(문자열, 시작점 [, 길이]) * []는 옵션
- 문자열의 원하는 부분만 잘라 반환해주는 함수
- 길이 명시X, 문자열 시작점~끝까지 반환
- cf. SQL Server(MSSQL) 경우, SUBSTRING(문자열)
- SUBSTR 예시
SELECT SUBSTR('블랙핑크제니', 3, 4) FROM DUAL;

8. LENGTH(문자열)
- 문자열 길이를 반환해주는 함수
- cf. SQL Server(MSSQL) 경우, LEN(문자열)
- LENGTH 예시
SELECT LENGTH('JENNIE') FROM DUAL;

9. REPLACE(문자열, 변경 전 문자열 [, 변경 후 문자열]) * []는 옵션
- 문자열에서 변경 전 문자열을 찾아 변경 후 문자열로 바꿔주는 함수)
- 변경 후 문자열 명시X, 문자열에서 변경 전 문자열 제거
- REPLACE 예시
SELECT REPLACE('블랙핑크제니', '제니', '지수') FROM DUAL;

- 변경 후 문자열 명시X REPLACE 경우 : 문자열에서 변경 전 문자열 제거
SELECT REPLACE('블랙핑크제니', '블랙') FROM DUAL;

3-2. 숫자 함수
1. ABS(수)
- 수의 절대값을 반환해주는 함수
- ABS 예시
SELECT ABS(-1) FROM DUAL;

2. SIGN(수)
- 수의 부호를 반환해주는 함수
- 양수면 1, 음수면 -1, 0이면 0 반환
- SIGN 예시
SELECT SIGN(-7) FROM DUAL;

3. ROUND(수 [, 자릿수]) * []는 옵션
- 수를 지정된 소수점 자릿수까지 반올림하여 반환해주는 함수
- 자릿수 명시X 경우, 기본값 0
- 반올림된 정수로 반환하고 자릿수 음수일 경우, 지정된 정수부를 반올림하여 반환
- 자릿수 양수 경우 ROUND : 지정된 소수점 자릿수까지 반올림해 반환
SELECT ROUND(163.76, 1) FROM DUAL;

- 자릿수 음수 경우 ROUND : 지정된 정수부 반올림해 반환
SELECT ROUND(163.76, -2) FROM DUAL

4. TRUNC(수 [,자릿수]) * []는 옵션
- 수를 지정된 소수점 자릿수까지 버림해 반환해주는 함수
- 자릿수 명시X, 기본값 0이고 버림된 정수로 반환
- 자릿수 음수, 지정된 정수부에서 버림하여 반환
- TRUNC 예시
SELECT TRUNC(54.29, 1) FROM DUAL;

- 자릿수 음수 TRUNC : 지정된 정수부에서 버림하여 반환
SELECT TRUNC(54.29, -1) FROM DUAL;

5. CEIL(수)
- 소수점 이하 수를 올림한 정수를 반환해주는 함수
- cf. SQL Server(MSSQL) 경우, CEILING(문자열)
- CEIL 예시
SELECT CEIL(72.86) FROM DUAL;

6. FLOOR(수)
- 소수점 이하 수를 버림한 정수를 반환해주는 함수
- FLOOR 예시
SELECT FLOOR(22.3) FROM DUAL;

7. MOD(수1, 수2)
- 수1을 수2로 나눈 나머지를 반환해주는 함수
- MOD 예시
SELECT MOD(15, -4) FROM DUAL;

3-3. 날짜 함수
1. SYSDATE
- 현재 연/월/일/시/분/초를 반환해주는 함수
- nls_date_format에 따라 sysdate 출력 양식 달라질 수 있음
- cf. SQL Server(MSSQL) 경우, GETDATE()
- SYSDATE 예시
SELECT SYSDATE FROM DUAL;

2. EXTRACT(특정 단위 FROM 날짜 데이터)
- 날짜 데이터에서 특정 단위(YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)만 출력해 반환해주는 함수
- cf. SQL Server(MSSQL) 경우, DATEPART(특정 단위, 날짜 데이터)
- EXTRACT 예시
SELECT EXTRACT(YEAR FROM SYSDATE) AS YEAR,
EXTRACT(MONTH FROM SYSDATE) AS MONTH,
EXTRACT(DAY FROM SYSDATE) AS DAY
FROM DUAL;

3. ADD_MONTHS(날짜 데이터, 특정 개월 수)
- 날짜 데이터에서 특정 개월 수를 더해 날짜를 반환해주는 함수
- 날짜 이전 달이나 다음 달에 기준 날짜의 일자가 존재하지 않으면, 해당 월의 마지막 일자가 반환됨
- cf. SQL Server(MSSQL) 경우, DATEADD(MONTH, 특정 개월 수, 날짜 데이터)
- ADD_MONTHS 예시
SELECT ADD_MONTHS(TO_DATE('2021-12-31', 'YYYY-MM-DD'), -1) AS PREV_MONTH
ADD_MONTHS(TO_DATE('2021-12-31', 'YYYY-MM-DD'), 1) AS NEXT_MONTH
FROM DUAL;

3-4. 변환 함수
1. 명시적 형변환&암시적 형변환
- 명시적 형변환 : 변환 함수를 사용해 데이터 유형 변환을 명시적으로 나타냄
- 암시적 형변환 : 데이터베이스가 내부적으로 알아서 데이터 유형을 반환함
- ex. 조건절에서 VARCHAR 유형의 BIRTHDAY 컬럼을 숫자와 비교할 경우, 데이터베이스는 오류를 뱉지 않고 내부적으로 BIRTHDAY 컬럼을 NUMBER형으로 변환하게 되는데 이럴 때 쓰이는 것이 암시적 형변환

- 암시적 형변환이 가능하다고 하여 컬럼의 데이터 유형을 고려 않고 SQL을 작성하면, 성능 저하/에러 경우 있어 명시적 형변환을 사용하는 것이 좋음
2. 명시적 형변환에 쓰이는 함수
- cf. SQL Server(MSSQL) 경우, CONVERT/CAST 함수 사용O
- TO_NUMBER(문자열) : 문자열 -> 숫자형 변환 함수
SELECT TO_NUMBER('1234') FROM DUAL;

SELECT TO_NUMBER('abc') FROM DUAL;

- TO_CHAR(수 or 날짜 [, 포맷]) * []는 옵션
- 수, 날짜형 데이터 -> 포맷 형식 문자형 변환 함수
SELECT TO_CHAR(1234) FROM DUAL;

SELECT TO_CATR(SYSDATE, 'YYYYMMDD HH24MISS') FROM DUAL;

- TO_DATE(문자열, 포맷) : 포맷 형식 문자형 데이터 -> 날짜형 변환

SELECT TO_DATE('20210602', 'YYYYMMDD') FROM DUAL;

3-5. NULL 관련 함수
1. NVL(인수1, 인수2)
- 인수1 값이 NULL인 경우, 인수2 반환
- 인수1 값이 NULL 아닌 경우, 인수1 반환
- NVL 예시
SELECT * FROM REVIEW;

SELECT MEMBER_NO,
NVL(REVIEW_SCORE, 0) AS REVIEW_SCORE
FROM REVIEW;

2. NULLIF(인수1, 인수2)
- 인수1, 인수2 같으면, NULL 반환
- 인수1, 인수2 다르면, 인수1 반환
- NULLIF 예시
SELECT * FROM REVIEW;

SELECT MEMBER_NO,
NULLIF(REVIEW_SCORE, 0) AS REVIEW_SCORE,
REVIEW
FROM REVIEW
WHERE PRODUCT_ID = '100001'

3. COALESCE(인수1, 인수2, 인수3, ...)
- NULL이 아닌 최초의 인수를 반환해주는 함수
- COALESCE 예시
SELECT * FROM MEMBERINFO;

SELECT NAME,
COALESCE(PHONE, EMAIL, FAX) AS CONTACT
FROM MEMBERINFO;

3-6. CASE
- 함수와 성격이 같으나 함수라기보다는 구문에 가까움
- 문장으로 '~이면 ~이고, ~이면 ~이다' 식으로 표현되는 구문
- 필요에 따라 각 CASE를 여러 개로 늘릴 수 있음
- cf. Oracle의 DECODE 함수와 같음
- CASE 예시
- 다음 구문은 모두 같은 결과값 반환
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'])
4. WHERE 절
INSERT 제외 DML문 수행 시 원하는 데이터만 골라 수행할 수 있도록 해주는 구문
- WHERE 절 위치
SELECT 컬럼명1, 컬럼명2 ... FROM 테이블명 WHERE 조건절;
UPDATE 테이블명 SET 컬럼명 = 새로운 데이터 WHERE 조건절;
DELETE FROM 테이블명 WHERE 조건절;
4-1. 비교 연산자

- CITY가 Paris인 행 조회하는 쿼리
SELECT FIRST_NAME, LAST_NAME, CITY
FROM MEMBER
WHERE CITY = 'Paris';

- MEMBER_NO가 10보다 작은 행 조회하는 쿼리
SELECT MEMBER_NO, FIRST_NAME, LAST_NAME
FROM MEMBER
WHERE MEMBER_NO < 10;

- 에러 발생하는 경우
- FIRST_NAME과 Mark의 데이터 타입 맞지 않음
- FIRST_NAME 같은 문자형 컬럼을 비교 조건으로 사용하려면, 우측 상수 값을 반드시 인용 부호로 감싸주어야 함
SELECT FIRST_NAME, LAST_NAME, EMAIL
FROM MEMBER
WHERE FIRST_NAME = Mark;

4-2. 부정 비교 연산자

- FAVORITIES가 Y 아닌 행 조회하는 쿼리
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE FAVORITES <> 'Y';

4-3. SQL 연산자

- PLAY_ID가 1이상 5이하 행 조회 쿼리
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE PLAY_ID BETWEEN 1 AND 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';

- NAME에 101이 포함된 행 조회 쿼리
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE NAME LIKE '%101%';

- TITLE이 IT Staff 이거나 IT Manager 행 조회 쿼리
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE TITLE IN ('IT Staff', 'IT Manager');
==
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE (TITLE = 'IT Staff' OR TITLE = 'IT Manager');

- COMAPANY가 NULL인 행 조회 쿼리
SELECT PLAY_ID, NAME, FAVORITES
FROM PLAY_LIST
WHERE COMPANY IS NULL;

4-4. 부정 SQL 연산자

- 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 BETWEEN 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 Manger');
==
SELECT LAST_NAME, FIRST_NAME, TITLE
FROM EMPLOYEE
WHERE NOT (TITLE IN ('IT Staff', 'IT Manger'));
==
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
WHERER (TITLE <> 'IT Staff' AND TITLE <> 'IT Manager');

- COMPANY가 NULL 아닌 행 조회
SELECT FIRST_NAME, LAST_NAME, COMPANY
FROM MEMBER
WHERE COMPANY IS NOT NULL;

4-5. 논리 연산자

- 논리 연산자 처리 순서 : () → NOT → AND → OR
- TITLE이 Sales Support Agent, CITY가 Calgary 행 조회 쿼리
SELECT LAST_NAME, FIRST_NAME, TITLE, CITY
FROM EMPLOYEE
WHERE TITLE = 'Sales Support Agent' AND CITY = 'Calgary';

- TITLE이 Sales Support Agent이거나 CITY가 Calgary 행 조회 쿼리
SELECT LAST_NAME, FIRST_NAME, TITLE, CITY
FROM EMPLOYEE
WHERE TITLE = 'Sales Support Agent' OR CITY = 'Calgary';

- TITLE이 Sales Support Agent이거나 CITY가 Calgary가 아닌 행 조회 쿼리
SELECT LAST_NAME, FIRST_NAME, TITLE, CITY
FROM EMPLOYEE
WHERE NOT (TITLE = 'Sales Support Agent' OR CITY = 'Calgary');
==
SELECT LAST_NAME, FIRST_NAME, TITLE, CITY
FROM EMPLOYEE
WHERE TITLE <> 'Sales Support Agent' AND CITY <> 'Calgary';

5. GROUP BY, HAVING 절
5-1. GROUP BY
- 데이터를 그룹별로 묶을 수 있도록 해주는 절
- GROUB BY + 그룹핑 기준 컬럼
- 컬럼은 하나 혹은 그 이상
5-2. 집계 함수

- 데이터를 그룹별로 나누면 그룹별로 집계 데이터 도출 가능해짐
- ex. 유투브 이용자 수를 국가별로 그룹핑하면 나라별로 이용자 수를 COUNT 해볼 수 있음
5-3. HAVING
- GROUP BY 절 사용 시 WHERE절 처럼 사용하는 조건절
- 주로 데이터 그룹핑 후 특정 그룹 골라낼 때 사용
- SELECT 문의 논리적 수행 순서
- SELECT --------- ⑤
- FROM ----------- ①
- WHERE --------- ②
- GROUP BY ---- ③
- HAVING --------- ④
- ORDER BY ----- ⑥
- HAVING 절은 논리적으로 GROUP BY 절 이후에 수행되어, 그룹핑 후 가능한 집계 함수로 조건 부여O
- ex. 2021년 7월 한 달 동안 판매 데이터를 상품 코드로 그룹핑해 COUNT 구하면 상품별 판매량이 나오고 HAVING 절을 이용해 한 달간 1000개 이상 팔린 상품만 출력
SELECT PRODUCT_CODE,
COUNT(ORDER_CNT) AS ORDER_CNT
FROM ORDER_PRODUCT
WHERE ORDER_DATE BETWEEN '20210701' AND '20210731'
GROUP BY PRODUCT_CODE
HAVING COUNT(ORDER_CNT) >= 1000;
- HAVING 절은 논리적으로 SELECT 절 전에 수행되어 SELECT 절에 명시되지 않은 집계 함수로도 조건 부여O
- 주의 : WHERE 절을 사용해도 되는 조건까지 HAVING 절로 사용하면 성능 상 불리할 수 있음(수행 시 오류X)
- WHERE 절에서 필터링이 선행되어야 GROUP BY 할 데이터량이 줄기 때문
- GROUP BY는 비교적 많은 비용이 드는 작업이라 수행 전 데이터량을 최소로 줄이는 것이 바람직
6. ORDER BY 절
6-1. ORDER BY
- SELECT 문에서 논리적으로 맨 마지막에 수행됨
- ORDER BY 절을 사용해 SELECT한 데이터 정렬O
- ORDER BY 절 따로 명시X, 데이터 임의 순서 출력
- ORDER BY 절 뒤 정렬 기준되는 컬럼은 하나 혹은 그 이상이고 옵션이 붙을 수 있음
- ASC(Ascending) : 오름차순
- DESC(Descending) : 내림차순
- 옵션 생략 시 ASC가 기본값
- 옵션 생략 기본값(ASC) ORDER BY 예시
SELECT NAME, MEMBER_NO FROM MEMBERINFO ORDER BY NAME;

- 옵션 DESC(내림차순) ORDER BY 예시
SELECT NAME, MEMBER_NO FROM MEMBERINFO ORDER BY NAME DESC;

- 옵션 혼합 ORDER BY 예시
SELCT GRADE, NAME, MEMBER_NO
FROM MEMBERINFO
ORDER BY GRADE DESC, NAME;

- tip. 정렬 기준 컬럼에 NULL 데이터 포함 경우, DB 종류 따라 정렬 위치 달라짐
- Oracle은 NULL을 최댓값으로 취급해 오름차순의 경우 맨 마지막에 위치(SQL Server는 반대)
- 순서 변경을 원한다면 ORDER BY 절에 NULLS FIRST, NULLS LAST 옵션을 사용해 NULL의 정렬 상 순서 변경O
7. JOIN
7-1. JOIN이란?
- 각기 다른 테이블을 한 번에 보여줄 때 쓰이는 쿼리
7-2. EQUI JOIN
- Equal(=) 조건으로 JOIN하는 것
- ex. 쇼핑몰에서 sqlchild라는 아이디 가진 사람이 온라인으로 마우스를 구매 후 리뷰 작성
- 마우스는 상품 테이블의 데이터, 리뷰는 리뷰 테이블에 저장
SELECT * FROM PRODUCT;

SELECT * FROM PRODUCT_REVIEW;

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;

무소음 무선 마우스 리뷰만 출력하고 싶다면, WHERE 조건 추가
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';

7-3. Non EQUI JOIN
- Equal(=) 조건이 아닌 다른 조건(BETWEEN, >, >=, <, <=)으로 JOIN 하는 방식
- ex. 이벤트 기간 동안 리뷰 작성 고객에게 사은품 주는 행사 진행 중 -> 리뷰 테이블&이벤트 테이블이 JOIN되어야 할 것
SELECT * FROM PRODUCT_REVIEW;

SELECT * FROM EVENT;

SELECT A.EVENT_NAME,
B.MEMBER_ID,
B.CONTENT,
B.REG_DATE
FROM EVENT A,
PRODUCT_REVIEW B
WHERE B.REG_DATE BETWEEN A.START_DATE AND A.END_DATE;

7-4. 3개 이상 TABLE JOIN
- ex. 상품/리뷰/이벤트 테이블 JOIN
SELECT A.PRODUCT_NAME,
B.MEMBER_ID,
B.CONTENT,
C.EVENT_NAME
FROM PRODUCT A,
PRODUCT_REVIEW B,
EVENT C
WHERE A.PRODUCT_CODE = B.PRODCUT_CODE
AND B.REG_DATE BETWEEN C.START_DATE AND C.END_DATE;

7-5. OUTER JOIN

- JOIN 조건에 만족하지 않는 행들도 출력됨
- LEFT OUTER JOIN 경우 LEFT/RIGHT TABLE 데이터 중 JOIN에 성공한 데이터와 성공하지 못한 나머지 LEFT TABLE의 데이터 함께 출력됨
- Oracle에서는 모든 행이 출력되는 테이블의 반대편 테이블의 옆에 (+) 기호 붙여 작성
8. STANDARD JOIN(표준 조인, ANSI JOIN)
- RDBMS의 벤더사가 많고 벤더마다 SQL 문법이 차이가 크면 호환성 이슈, 효율성 문제 등 발생으로 표준이 되는 ANSI SQL을 지정함
- STANDARD JOIN은 ANSI SQL 중 하나로 Oracle, MySQL에서도 돌아가는 JOIN 쿼리
8-1. INNER JOIN
- JOIN 조건에 충족하는 데이터만 출력됨

- JOIN 조건을 ON 절을 사용해 작성해야 함
- INNER JOIN 예시
SELECT * FROM PRODUCT;

SELECT * FROM PRODUCT_REVIEW;

SELECT A.PRODUCT_CODE,
A.PRODUCT_NAME,
B.MEMBER_ID,
B.CONTECT,
B.REG_DATE
FROM PRODUCT A INNER JOIN PRODUCT_REVIEW B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;

8-2. OUTER JOIN
- JOIN 조건에 충족하는 데이터가 아니어도 출력될 수 있는 방식
1. LEFT OUTER JOIN

- SQL에서 왼쪽에 표기된 테이블 데이터는 무조건 출력되는 JOIN
- 오른쪽 테이블에 JOIN되는 데이터 없는 Rows는 오른쪽 테이블 컬럼 값이 NULL로 출력됨
- LEFT OUTER JOIN 예시
SELECT A.PRODUCT_CODE,
A.PRODCUT_NAME,
B.MEMBER_ID,
B.CONTENT,
B.REG_DATE
FROM PRODUCT A LEFT OUTER JOIN PRODUCT_REVIEW B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;

2. RIGHT OUTER JOIN

- SQL에서 오른쪽에 표기된 테이블 데이터는 무조건 출력되는 JOIN
- 왼쪽 테이블에 JOIN되는 데이터 없는 Rows는 오른쪽 테이블 컬럼 값이 NULL로 출력됨
- RIGHT OUTER JOIN 예시
SELECT A.MEMBER_ID,
A.CONTENT,
A.REG_DATE,
B.PRODUCT_CODE,
B.PRODUCT_NAME
FROM PRODUCT_REVIEW A RIGHT OUTER JOIN PRODUCT BY B
ON A.PRODUCT_CODE = B.PRODUCT_CODE;

3. FULL OUTER JOIN
- 왼쪽, 오른쪽 테이블 데이터 모두 출력되는 방식
- LEFT/RIGHT OUTER JOIN의 합집합(단, 중복값 제거)
- FULL OUTER JOIN 예시
SELECT * FROM RUNNING_MAN;

SELECT * FROM INFINITE_CHALLENGE;

SELECT A.CAST AS R_CAST,
B.CAST AS I_CAST
FROM RUNNING_MAN A FULL OUTER JOIN INFINITE_CHALLENGE B
ON A.CAST = B.CAST;

8-3. NATURAL JOIN
- A/B 테이블에서 같은 이름 가진 컬럼들이 동일한 데이터 가질 경우 JOIN되는 방식
- NATURAL JOIN 예시
SELECT *
FROM RUNNING_MAN NATURAL JOIN INFINITE_CHALLENGE B;

- ex. INFINITE_CHALLENGE 테이블의 유재석의 JOB을 MC로 바꾸면?
SELECT * FROM INFINITE_CHALLENGE;

SELECT *
FROM RUNNING_MAN A NATURAL JOIN INFINITE_CHALLENGE B;

유재석 Row는 같은 이름 컬럼 중 JOB 컬럼이 동일X 데이터 갖고 있어, JOIN 시 출력X
- cf. Oracle에서는 USING 조건절 이용해 같은 이름 가진 컬럼 중 원하는 컬럼만 JOIN에 이용할 수 있음
SELECT CAST,
GENDER,
A.JOB AS R_JOB,
B.JOB AS I_JOB
FROM RUNNING_MAN A JOIN INFINITE_CHALLENGE B
USING (CAST, GENDER);
단, SELECT 절에서 USING 절로 정의된 컬럼 앞에서는 별도의 ALIAS나 테이블명 붙이지 않아야 함
8-4. CROSS JOIN

- A/B 테이블 사이에 JOIN 조건 없는 경우, 조합할 수 있는 모든 경우 출력
- Cartesian Product라고도 함
- CROSS JOIN 예시
SELECT NAME, JOB, BIRTHDAY FROM ENTERTAINER;

SELECT DRINT_CODE, DRINK_NAME FROM DRINK;

SELECT A.NAME,
A.JOB,
A.BIRTHDAY,
B.DRINK_CODE,
B.DRINK_NAME
FROM ENTERTAINER A CROSS JOIN DRINK B;

'Computer Science > Database' 카테고리의 다른 글
| 관리 구문 (0) | 2024.03.02 |
|---|---|
| SQL 활용 (0) | 2024.02.29 |
| 데이터 모델과 SQL (0) | 2024.02.27 |
| 데이터 모델링의 이해 (0) | 2024.02.27 |
| 엔터티 (0) | 2024.02.26 |
소중한 공감 감사합니다