
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
'프로그래밍언어 > 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 |

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
'프로그래밍언어 > 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 |