다양한 쿼리를 알아보자.
이번 글에서는 VIEW, GROUP BY, ORDER BY 등 여러 가지 개념에 대해 알아보겠습니다.
VIEW
VIEW(뷰)란 하나 이상의 테이블에서 데이터를 조회하는 가상 테이블입니다.
이때, 데이터는 실제로 저장되지 않고, SQL 쿼리 결과를 테이블 처럼 사용할 수 있습니다.
VIEW는 다음과같은 특징을 가지고 있습니다.
- 재사용 가능
- 복잡한 쿼리를 단순화하여 재사용 가능
- 데이터 보안
- 특정 열이나 행만 보여줌으로써 데이터 접근을 제한
- 데이터 일관성
- 동일한 데이터를 여러 쿼리에서 강요할 때 일관된 결과를 제공
CREATE VIEW 학생_정보 AS
SELECT 학번, 이름, 나이 FROM 학생 WHERE 나이 > 20;
SELECT * FROM 학생_정보;
해당 쿼리를 통해 학생 테이블에서 나이가 20살 초과인 학생의 학번, 이름, 나이만을 가지고 있는 학생_정보 VIEW를 생성
SELECT 문의 처리 순서
DML 쿼리를 실행에 순서가 있습니다.
- FROM: 데이터를 가져올 테이블 지정.
- WHERE: 행을 필터링.
- GROUP BY: 행을 그룹화.
- HAVING: 그룹화된 결과에 조건을 적용.
- SELECT: 필요한 열을 선택.
- DISTINCT: 중복된 데이터를 제거.
- ORDER BY: 결과를 정렬.
FROM -> ORDER BY 순 입니다.
이는 아주아주 중요하니 꼭 기억하시기 바랍니다.
SELECT ~ FOR UPDATE
이 구문에 대해 처음 보시는 분들도 많으실 거라 생각합니다.
해당 구문은 SELECT 문으로 데이터를 읽는 동시에 행에 대한 잠금을 거는 구문입니다.
이를 통해 다른 트랜잭션이 해당 행을 수정하지 못하도록 잠금을 설정할 수 있으며, 이를 통해 데이터에 오류가 생기는 것을 방지할 수 있습니다.
START TRANSACTION;
SELECT * FROM 학생 WHERE 학번 = 1 FOR UPDATE;
UPDATE 학생 SET 나이 = 25 WHERE 학번 = 1;
COMMIT;
GROUP BY
GROUP BY는 데이터를 특정 열을 기준으로 그룹화하여 집계함수(COUNT, SUM, AVG...)를 사용할 때 사용됩니다.
GROUP BY는 다음과 같은 특징을 가지고 있습니다.
- 집계함수가 필수적으로 사용됩니다.
- HAVING 절과 함께 그룹화된 데이터에 조건을 걸 수 있습니다.
SELECT 학과, COUNT(*) AS 학생수
FROM 학생
GROUP BY 학과;
ORDER BY
ORDER BY는 결과를 특정 열이나 표현식을 기준으로 정렬할 때 사용됩니다.
ORDER BY는 다음과 같은 특징을 가지고 있습니다.
- 기본 정렬 순서는 오름차순 (ASC)
- 내림차순(DESC) 옵션도 지원
SELECT 이름, 나이 FROM 학생 ORDER BY 나이 ASC; -- 나이 오름차순
SELECT 이름, 나이 FROM 학생 ORDER BY 나이 DESC; -- 나이 내림차순
INNER JOIN과 OUTER JOIN의 차이점
INNER JOIN은 두 테이블 간 공통된 값을 기준으로 데이터를 반환합니다.
OUTER JOIN은 공통된 값뿐만 아니라, 한쪽 테이블에만 존재하는 값도 포함됩니다.
OUTER JOIN은 다음과 같이 나뉩니다.
- LEFT OUTER JOIN
- RIGHT OUTER JOIN
- FULL OUTER JOIN
LEFT OUTER JOIN은
- 왼쪽 테이블의 모든 데이터와, 오른쪽 테이블에서 매칭되는 데이터를 반환
- 매칭되지 않은 오른쪽 테이블 값은 NULL로 표시
RIGHT OUTER JOIN은
- 오른쪽 테이블의 모든 데이터와, 왼쪽 테이블에서 매칭되는 데이터를 반환
- 매칭되지 않는 왼쪽 테이블 값은 NULL로 표시
-- LEFT OUTER JOIN
SELECT 학생.학번, 수강.과목
FROM 학생
LEFT OUTER JOIN 수강 ON 학생.학번 = 수강.학번;
-- RIGHT OUTER JOIN
SELECT 학생.학번, 수강.과목
FROM 학생
RIGHT OUTER JOIN 수강 ON 학생.학번 = 수강.학번;
FULL OUTER JOIN은
- 두 테이블의 모든 데이터를 포함하며, 양쪽 테이블에서 매칭되지 않는 데이터도 포함합니다.
- 매칭되지 않는 데이터는 해당 열에 NULL로 표시됩니다.
- LEFT OUTER JOIN + RIGHT OUTER JOIN의 결합과 동일한 결과
- 공통된 값은 하나로 합쳐지고, 매칭되지 않는 값도 결과에 포함
- 일부 데이터베이스에서는 FULL OUTER JOIN을 지원하지 않으며, 이를 대신 UNION으로 구현 가능
추가로 CROSS JOIN에 대해서 알아보겠습니다.
CROSS JOIN은
- 두 테이블의 모든 행의 카티션 곱(Cartesian Product)을 반환
- 각 행이 다른 테이블의 모든 행과 결합
SELECT A.이름, B.과목
FROM 학생 A
CROSS JOIN 수강 B;
이 쿼리의 결과는 학생 테이블 행 수 x 수강 테이블의 행 수 가 됩니다.
서브쿼리
서브쿼리는 쿼리 내부에 중첩된 쿼리를 의미합니다. 이때 만들어진 내부 쿼리 결과는 외부 쿼리에서 사용됩니다.
서브쿼리에는 다음과 같은 종류가 있습니다.
- 스칼라 서브쿼리 : 하나의 값 반환, 주로 WHERE, SELECT, HAVING 절에 주로 사용
- 다중 행 서브쿼리 : 여러 행 반환, 주로 IN, ANY 또는 ALL과 같은 연산자와 함께 사용
- 다중 열 서브쿼리 : 여러 열 반환, 주로
-- 스칼라 서브쿼리 -> 학생의 학번중 가장 큰 학번이 내부 쿼리의 결과가 됩니다.
SELECT 이름 FROM 학생 WHERE 학번 = (SELECT MAX(학번) FROM 학생);
-- 다중 행 서브쿼리 -> 수강 과목이 수학인 학번을 모두 갖져오며 이는 내부 쿼리의 결과가 됩니다.
SELECT 이름 FROM 학생 WHERE 학번 IN (SELECT 학번 FROM 수강 WHERE 과목 = '수학');
-- 다중 열 서브쿼리
SELECT * FROM 학생 WHERE (학번, 나이) IN (
SELECT 학번, 나이
FROM 수강
WHERE 과목 = '수학'
);
DISTINCT
DISTINCT는 SELECT 결과에서 중복된 데이터를 제거합니다.
SELECT DISTINCT 학과 FROM 학생;
이는 학생 테이블에서 학과를 중복되지 않게 가져옵니다.