NATURAL JOIN์๋ ON ์ ์ธ ์ ์๋ค.
SELECT A.COL1, B.COL2
FROM SAMPLE1 A NATURAL JOIN SAMPLE B
ON A.COL1 = B.COL1
Oracle์ ๊ฒฝ์ฐ OUTER JOIN ์์ฑ ์ (+) ๊ธฐํธ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ข๋ณ์ด๋ ์ฐ๋ณ ์ค ํ๋์๋ง ํ๊ธฐํด์ผ ํ๋ค.
SELECT A.COL1, B.COL2
FROM SAMPLE1 A, SAMPLE B
WHERE A.COL1(+) = B.COL1(+);
FULL OUTER JOIN์ ๊ตฌํํ๊ธฐ ์ํด์๋ (+) ๊ธฐํธ ๋์ ํ์ค SQL ๊ตฌ๋ฌธ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. Oracle 9i ์ดํ๋ถํฐ๋ ํ์ค SQL FULL OUTER JOIN ๊ตฌ๋ฌธ์ ์ง์ํ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ ํ์์ผ๋ก ์์ฑํด์ผ ํฉ๋๋ค:
SELECT A.COL1, B.COL2
FROM TABLE_A A
FULL OUTER JOIN TABLE_B B
ON A.COL1 = B.COL1;
์ด์ ๊ฐ์ด ํ์ค FULL OUTER JOIN ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ฉด ์์ชฝ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ๋ชจ๋ ํฌํจ๋๋ฉฐ, ์ด๋ ํ์ชฝ์ ๊ฐ์ด ์๋๋ผ๋ ๊ฒฐ๊ณผ์ ํ์๋ฉ๋๋ค. (+) ๊ธฐํธ๋ FULL OUTER JOIN์์๋ ์ฌ์ฉํ ์ ์๊ณ , LEFT ๋๋ RIGHT์ OUTER JOIN์์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
Oracle์ ๊ฒฝ์ฐ (+)๋ก OUTER JOIN ์์ฑ ์ ON์ ์ ์กฐ๊ฑด์ WHERE์ ์ ํํ๋๋ค.
SELECT A.COL1, B.COL2
FROM TABLE_A A, TABLE_B B
WHERE A.COL1 = B.COL1(+);
SELECT A.COL1, B.COL2
FROM TABLE_A A
LEFT OUTER JOIN TABLE_B B
ON A.COL1 = B.COL1;
JOIN์์ USING์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ USING์ ๋ก ์ ์๋ ์ปฌ๋ผ ์์๋ ๋ณ๋์ ํ ์ด๋ธ๋ช ์ด๋ ALIAS๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
SELECT B.COL1, B.COL2
FROM SAMPLE1 A JOIN SAMPLE2 B
USING (COL1, COL2);
BETWEEN ์ ์ SQL์์ ๋ฒ์๋ฅผ ์ง์ ํ ๋ ์ฌ์ฉํ๋ ์ฐ์ฐ์์ด๋ฉฐ, ์์ ๊ฐ๊ณผ ๋ค์ ๊ฐ ๋ชจ๋ ํฌํจ
์ด์, ์ดํ ๊ฐ๋ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ํธํจ
SELECT COUNT(*)
FROM MEMBER
WHERE REGISTER_DATE BETWEEN TO_DATE('20230101') AND TO_DATE('20240101');
// ์๋ 20240101์ธ ํ์๋ฐ์ดํฐ๊น์ง COUNT
NULL๊ณผ์ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ False์ด๋ฏ๋ก ์กฐ๊ฑด๊ฐ์ด ๋ ๊ฑฐ์ง์ด๋์ด ์๋ฌด ๋ฐ์ดํฐ๋ ์ถ๋ ฅ๋์ง ์๋๋ค. = ๋ ์ฐ์ฐ์.
SELECT COL1 FROM SAMPLE WHERE COL2 = NULL;
NATURAL JOIN์ ๋ ํ ์ด๋ธ์์ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง ์ปฌ๋ผ๋ค์ด ๋ชจ๋ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ ๊ฒฝ์ฐ JOIN์ด ๋๋ ๋ฐฉ์์ผ๋ก ๊ณตํต ์ปฌ๋ผ ์์ ํ ์ด๋ธ๋ช ์ด๋ ALIAS๋ฅผ ๋ถ์ด๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
SELECT D.DEPT_NO, EMP.EMP_ID
FROM EMP E LEFT OUTER JOIN DEPT D;
CASE WHEN ์ ์ CNT ์ธ ์ ์๋ค.
CASE WHEN CNT < 10 THEN 'S'
CASE WHEN CNT < 20 THEN 'M'
CASE WEHN ์ ์ ๋ง์ง๋ง DEFAULT ๊ฐ๋ง ELSE๋ฅผ ๊ธฐ์ ํด์ผ ํ๋ค
CASE WHEN COUNT(*) < 10 THEN 'S'
ELSE COUNT(*) < 20 THEN 'M'
ELSE 'L'
๋ฌธ์ ์์ GROUP BY๊ฐ ๋น ์ก๋์ง๋ ์ ๋ณด๊ธฐ
โญ** `ORDER BY` ์ ์ SELECT ์ ์ ๊ธฐ์ ๋ ALIAS๋ฅผ ์ฌ์ฉ ํ ์ โญ **
โญ** `HAVING` ์ ์ SELECT ์ ๋ณด๋ค ๋จผ์ ์ํ๋๋ฏ๋ก SELECT ์ ์์ ๊ธฐ์ ๋ ALIAS ์ฌ์ฉํ ์ โ**
CHAR ๋ฐ์ดํฐ ํ์ ์ ๊ณ ์ ๊ธธ์ด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋ฌธ์์ด ๋ฐ์ดํฐ์ด๋ค. COL2์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ํ์ ์ด CHAR(5)์ด๊ธฐ ๋๋ฌธ์ ์ปฌ๋ผ๊ฐ์ ๊ธธ์ด๊ฐ 3์ธ ๊ฒฝ์ฐ ๋๋จธ์ง 2์๋ฆฌ๋ ๊ณต๋ฐฑ์ผ๋ก ์ฑ์์ ๊ณ ์ ๊ธธ์ด๋ฅผ ์ ์งํ๊ฒ ๋๋ค.
CREATE TABLE SAMPLE (
COL1 VARCHAR(5)
COL2 CHAR(5)
);
[SAMPLE ํ ์ด๋ธ]
COL1 | COL2 |
SQL | SQL |
// ๋ค๋ฅธ ์ฟผ๋ฆฌ
SELECT * FROM SAMPLE WHERE COL1 = COL2;
// ์๋๋ ๊ฐ์ ์ฟผ๋ฆฌ
SELECT * FROM SAMPLE WHERE COL1 = TRIM(COL2);
SELECT * FROM SAMPLE WHERE COL1 <> COL2;
SELECT * FROM SAMPLE WHERE COL1 = RTRIM(COL2);
โญ HAVING ์ ์ ์ฃผ๋ก GROUP BY ์ ๋ค์ ์ค๋ฉด์ ์ง๊ณ ๋ฐ์ดํฐ์ ๋ํ ์กฐ๊ฑด์ ๋ถ์ฌํ์ง๋ง ํ ์ด๋ธ ์ ์ฒด๊ฐ ํ ๊ฐ์ ๊ทธ๋ฃน์ด ๋๋ ๊ฒฝ์ฐ HAVING๋ง ๋จ๋ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
SELECT SUM(COL) FROM SAMPLE HAVING SUM(COL) > 50;
[SAMPLE ํ ์ด๋ธ]
COL
10
20
30
์๋ธ์ฟผ๋ฆฌ
ํ๋์ ์ฟผ๋ฆฌ ์์ ์กด์ฌํ๋ ๋ ๋ค๋ฅธ ์ฟผ๋ฆฌ
SELECT์ , ORDER BY์ ์ธ | ์ค์นผ๋ผ ์๋ธ์ฟผ๋ฆฌ(Scalar Subquery) |
FROM์ | ์ธ๋ผ์ธ ๋ทฐ(Inline View) |
WHERE์ , HAVING์ | ์ค์ฒฉ ์๋ธ์ฟผ๋ฆฌ(Newsted Subquer) |
โ ์๋ธ์ฟผ๋ฆฌ์๋ ๋ฐ๋์ ๋ฉ์ธ์ฟผ๋ฆฌ์ ์ปฌ๋ผ์ด ํฌํจ๋์ด์ผ ํ๋ค.
๋ฉ์ธ์ฟผ๋ฆฌ์ ์ปฌ๋ผ์ด ํฌํจ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ, ๋ฉ์ธ์ฟผ๋ฆฌ์ ์ปฌ๋ผ์ด ํฌํจ๋์ง ์์ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋น์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ๋ผ๊ณ ํ๋ค.
โญ ์๋ธ์ฟผ๋ฆฌ๋ ORDER BY ์ , INSERT ๋ฌธ์ VALUE ์ , UPDATE๋ฌธ์ SET ์ ๋ฑ์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
1. ๋น์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ (Non-correlated Subquery)
๋น์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ๋ ๋ฉ์ธ ์ฟผ๋ฆฌ์ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋๋ค. ์๋ธ์ฟผ๋ฆฌ๊ฐ ํ ๋ฒ๋ง ์คํ๋์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฉ์ธ ์ฟผ๋ฆฌ์์ ์ฌ์ฉํ๋ค.
SELECT employee_id, name
FROM employees
WHERE department_id = (SELECT department_id
FROM departments
WHERE department_name = 'Sales');
์ด ๊ฒฝ์ฐ, `SELECT department_id FROM departments WHERE department_name = 'Sales'`๋ ๋ฉ์ธ ์ฟผ๋ฆฌ์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ๋ฒ ์คํ๋์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค. ๋ฉ์ธ ์ฟผ๋ฆฌ๋ ํด๋น ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ์ฌ employees ํ ์ด๋ธ์์ department_id๊ฐ ์ผ์นํ๋ ํ์ ์กฐํํ๋ค.
2. ์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ (Correlated Subquery)
์๋ธ์ฟผ๋ฆฌ ๋ด์ ๋ฉ์ธ์ฟผ๋ฆฌ์ ์ปฌ๋ผ์ด ์กด์ฌํ์ง ์๋๋ค.
์ฐ๊ด ์๋ธ์ฟผ๋ฆฌ๋ ๋ฉ์ธ ์ฟผ๋ฆฌ์ ๊ฐ ํ์ ๋ํด ๋ฐ๋ณต ์คํ๋๋ค. ์๋ธ์ฟผ๋ฆฌ๊ฐ ๋ฉ์ธ ์ฟผ๋ฆฌ์ ๊ฐ์ ์ฐธ์กฐํ๋ค.
SELECT e.employee_id, e.name
FROM employees e
WHERE e.salary > (SELECT AVG(salary)
FROM employees
WHERE department_id = e.department_id);
์๋ฃ๋ณ ๊ฐ์ฅ ๋ง์ ์ฃผ๋ฌธ์๋์ ๊ฐ์ง ์ฃผ๋ฌธ๋ฒํธ ์กฐํํ๋ ์๋ธ์ฟผ๋ฆฌ
SELECT ORDER_NO,
DRINK_CODE,
ORDER_CNT
FROM CAFE_ORDER A
WHERE ORDER_CNT = (SELECT MAX(ORDER_CNT)
FROM CAFE_ORDER B
WHERE B.DRINK_CODE = A.DRINK_CODE);
3. ์ค์ฒฉ ์๋ธ์ฟผ๋ฆฌ(Nested Subquery)
๋จ์ผ ํ(Single Row) ์๋ธ์ฟผ๋ฆฌ | - ์๋ธ์ฟผ๋ฆฌ๊ฐ 1๊ฑด ์ดํ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ - ๋จ์ผ ํ ๋น๊ต ์ฐ์ฐ์์ ํจ๊ป ์ฌ์ฉ - =, <, >, <=, >=, <> |
๋ค์ค ํ(Multi Row) ์๋ธ์ฟผ๋ฆฌ | - ์๋ธ์ฟผ๋ฆฌ๊ฐ ์ฌ๋ฌ ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ - ๋ค์ค ํ ๋น๊ต ์ฐ์ฐ์์ ํจ๊ป ์ฌ์ฉ - IN, ALL, ANY, SOME, EXISTS |
๋ค์ค ์ปฌ๋ผ(Multi Column) ์๋ธ์ฟผ๋ฆฌ | ์๋ธ์ฟผ๋ฆฌ๊ฐ ์ฌ๋ฌ ์ปฌ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ |
ํค๋ ๊ฐ์ ์ฒซ๋ฒ์งธ ์ฟผ๋ฆฌ ๋ฐ๋ผ๊ฐ
SELECT ENAME AS EN,
JOB_ID AS JB
FROM EMP
WHERE DEPT_NO IN ('90', '60')
INTERSECT
SELECT ENAME AS NM,
JOB_ID AS JI
FROM EMP
WHERE JOB_ID IN ('AD_VP', 'FI_ACCOUNT');
์๋ ์ฟผ๋ฆฌ์์ ๊ฒฐ๊ณผ ์ปฌ๋ผ ํค๋๋ EN JB
'Coding > SQL&DataBase' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SQLD] JOIN (Inner, Outer, Self, Natural, Cross JOIN) (6) | 2024.11.17 |
---|---|
[SQLD] NULL ๊ด๋ จ ํจ์, CASE, DECODE, SQL์คํ์์ (5) | 2024.11.16 |
[SQLD] SQL ๊ธฐ๋ณธ ํจ์ (๋ฌธ์์ด, ์ซ์, ๋ ์ง ๋ฑ) (7) | 2024.11.16 |
[SQLD] ์ ๊ทํ, ๋ฐ์ ๊ทํ (36) | 2024.11.16 |
[SQLD] ๋ฐ์ดํฐ๋ชจ๋ธ๋ง์ ์ดํด (6) | 2024.11.16 |