💽 DataBase

SQL 데이터 조회

SELECT로 데이터 조회

Select Statement

  • ID가 9인 임직원의 이름과 직군을 알고 싶다.
notion image

Projection Attributes

관심있는 Attributes
notion image
  • 교차가 되는 두 값만 가져옴
    • notion image

정리

notion image

Select Statement

  • Project 2002를 리딩하는 임직원의 ID와 이름, 직군을 찾자
notion image
notion image
notion image
notion image
notion image

AS

Table이나 Attribute에 별칭(Alias)을 붙일 때 사용
  • 생략 가능
notion image
notion image
notion image

생략

notion image

DISTINCT

Select 결과에서 중복되는 Tuple들을 제외하고 싶을 때 사용

Distinct Statement

  • 디자이너들이 참여하고 있는 프로젝트들의 ID와 이름을 알고 싶다.
notion image
notion image
notion image

중복 제거

notion image
notion image

LIKE

Like Statement

  • 이름이 N으로 시작하거나, N으로 끝나는 임직원들의 이름을 알고 싶다.
notion image
notion image

Like Statement

  • 이름에 NG가 들어가는 임직원들의 이름을 알고 싶다.
notion image
notion image

Like Statement

  • 이름이 J로 시작하는, 총 4 글자의 이름을 가지는 임직원들의 이름
notion image
notion image

Escape 문자와 함께

  • %로 시작하거나 _로 끝나는 프로젝트 이름을 찾고 싶을 때
notion image

정리

notion image

* (asterisk)

선택된 Tuple들의 모든 Attribute들을 보여주고 싶을 때 사용
  • ID가 9인 임직원의 모든 Attribute들을 알고 싶다.
notion image
notion image
notion image
notion image

SELECT without WHERE

Table에 있는 모든 Tuple들을 반환

Statement

  • 모든 임직원의 이름과 생일을 알고 싶다.
notion image
notion image

주의사항

  1. SELECT로 조회할 때 조건들을 포함해서 조회하면, 이 조건들과 관련된 Attributes에 Index가 걸려있어야 한다.
    1. 그렇지 않으면, 데이터가 많아질수록 조회 속도가 느려진다.
    2. notion image
  1. 이 자료는 MySQL 기준

Subquery

SELECT with subquery

  • ID가 14인 임직원보다 생일이 빠른 임직원의 ID, 이름, 생일을 알고 싶다.
notion image
notion image
notion image
  • 두번의 쿼리로 나누어 실행된 쿼리를 하나의 쿼리로
notion image

subquery(nested query or inner query)

SELECT, INSERT, UPDATE, DELETE에 포함된 query
  • subquery는 () 안에 기술된다.

outer query(main query)

subquery를 포함하는 query

Statement

  • ID가 1인 임직원과 같은 부서, 같은 성별인 임직원들의 ID와 이름, 직군을 알고 싶다.
notion image
  • ID가 5인 임직원과 같은 프로젝트에 참여한 임직원들의 ID를 알고 싶다.
notion image
notion image
notion image
notion image
notion image
notion image

IN

notion image
  • Unqualified Attribute가 참조하는 Table은 해당 Attribute가 사용된 query를 포함하여 그 query 바깥쪽으로 존재하는 모든 query들 중에 해당 Attribute 이름을 가지는 가장 가까이에 있는 Table을 참조

Statement

  • ID가 5인 임직원과 같은 프로젝트에 참여한 임직원들의 ID와 이름을 알고 싶다.
notion image

From에 subquery

notion image

EXISTS

Statement

  • ID가 7 or 12인 임직원이 참여한 프로젝트의 ID와 이름을 알고 싶다.
notion image

정리

  • Correlated Query: subquery가 바깥쪽 query의 Attribute를 참조할 때, Correlated Subquery라 부름
  • EXISTS: subquery의 결과가 최소 하나의 row라도 있다면 TRUE를 반환
  • NOT EXISTS: subquery의 결과가 단 하나의 row라도 없다면 TRUE를 반환

IN으로 바꿀 수 있음

notion image

Statement

  • 2000년대생이 없는 부서의 ID와 이름을 알고 싶다.
notion image

IN으로 바꿈

notion image

ANY

Statement

  • 리더보다 높은 연봉을 받는 부서원을 가진 리더의 ID와 이름, 연봉을 알고 싶다.
notion image
notion image

정리

  • v comparison_operator ANY (subquery): subquery가 반환한 결과들 중에 단 하나라도 v와의 비교 연산이 TRUE라면, TRUE 반환
  • SOME도 ANY와 같은 역할을 한다.

Statement

  • 리더보다 높은 연봉을 받는 부서원을 가진 리더의 ID와 이름, 연봉, 해당 부서 최고 연봉을 알고 싶다.

SELECT 절에도 subquery 들어갈 수 있음

notion image
notion image

ALL

Statement

  • ID가 13인 임직원과 한번도 같은 프로젝트에서 참여하지 못한 임직원들이 ID, 이름, 직군을 알고 싶다.
notion image

정리

  • v comparison_operator ALL (subquery): subquery가 반환된 결과들과 v와의 비교 연산이 모두 TRUE라면, TRUE 반환

참고사항

  1. 성능 비교: IN vs EXISTS
    1. 최근에는 거의 차이 없음
  1. MySQL 기준

NULL

  • Unknown
  • Unavailable or withheld
  • not applicable

SQL에서 NULL의 의미

notion image
  • id 14, 15의 생일이 같은 NULL이라고 하면, 생일이 같은 것인가?
notion image
  • 생일이 NULL인 것이 없는게 아니다!

IS

notion image
notion image

NULL과 Three-Valued Logic

notion image
notion image
  • 여기서 이 명령을 실행하면 FALSE가 나올 것이라 예상하지만
  • 결과는 UNKNOWN
  • TRUE 일 수도 있고, FALSE 일 수도 있다라는 의미
  • Three-Valued Logic: 비교/논리 연산의 결과로 TRUE, FALSE, UNKNOWN을 가진다.
notion image
notion image

WHERE 절의 Conditions

WHERE 절에 있는 condition의 결과가 TRUE인 Tuple들만 선택된다.
  • 결과가 FALSE거나 UNKNOWN이면 Tuple은 선택되지 않는다.

NOT IN 사용 시 주의 사항

v NOT IN(v1, v2, v3)
v != v1 AND v != v2 AND v != v3
  • 만약 v1, v2, v3 중 하나가 NULL 이라면?
notion image

UNKNOWN 해결 방안

NOT NULL Constraint

IS NOT NULL 사용

notion image

NOT EXISTS 사용

notion image

JOIN

두 개 이상의 Table들에 있는 데이터를 한 번에 조회하는 것
  • 여러 종류의 JOIN이 존재

Statement

  • ID가 1인 임직원이 속한 부서의 이름?
notion image
notion image

Implicit JOIN

FROM 절에는 Table들만 나열, WHERE 절에 JOIN Condition을 명시
  • Old-Style JOIN Syntax
  • WHERE 절에 Selection Condition과 JOIN Condition이 같이 있기 때문에 가독성이 떨어짐
  • 복잡한 JOIN 쿼리를 작성하다 보면 잘못된 쿼리를 작성할 가능성이 크다.

Explicit JOIN

FROM 절에 JOIN 키워드와 함께 Joined Table들을 명시하는 방식
  • FROM 절에서 ON 뒤에 Join Condition이 명시됨
  • 가독성이 좋음
  • 복잡한 JOIN 쿼리 작성 중에도 실수할 가능성이 적다.
notion image

INNER JOIN

두 Table 사이에서 JOIN Condition을 만족하는 Tuple들로만 Result Table을 만드는 JOIN
  • JOIN 키워드 앞에 INNER가 생략되어있는 것
  • FROM table1 [INNER] JOIN table2 ON join_condition
  • Join Condition에 사용 가능한 연산자(Operator): =, <, >, ≠ 등 여러 비교 연산자 가능
  • Join Condition에서 NULL값을 가지는 Tuple은 Result Table에 포함되지 못한다.
notion image
notion image

OUTER JOIN

두 Table에서 Join Condition을 만족하지 않는 Tuple들도 Result Table에 포함하는 JOIN
  • FROM table1 LEFT [OUTER] JOIN table2 ON join_condition
  • FROM table1 RIGHT [OUTER] JOIN table2 ON join_condition
  • FROM table1 FULL [OUTER] JOIN table2 ON join_condition
  • Join Condition에 사용 가능한 연산자(Operator): =, <, >, ≠ 등 여러 비교 연산자 가능

LEFT OUTER JOIN

notion image
notion image

RIGHT OUTER JOIN

notion image
notion image

FULL OUTER JOIN

MySQL에서는 지원하지 않음
notion image
notion image

EQUI JOIN

Join Condition에서 = (Equality Comparator)를 사용하는 JOIN
  • INNER JOIN, OUTER JOIN 상관 없이 = 를 사용한 JOIN이라면 EQUI JOIN으로 보는 경우
  • INNER JOIN으로 한정해서 = 를 사용한 JOIN만 EQUI JOIN으로 보는 경우
notion image

USING

두 Table이 EQUI JOIN 할 때 JOIN하는 Attribute의 이름이 같다면, USING으로 간단하게 작성
  • 이 때, 같은 이름의 Attribute는 Result Table에서 한번만 표시됨
  • FROM table1 [INNER] JOIN table2 USING (attributes)
  • FROM table1 LEFT [OUTER] JOIN table2 USING (attributes)
  • FROM table1 RIGHT [OUTER] JOIN table2 USING (attributes)
  • FROM table1 FULL [OUTER] JOIN table2 USING (attributes)
notion image
notion image

NATURAL JOIN

두 Table에서 같은 이름을 가지는 모든 Attribute Pair에 대해서 EQUI JOIN을 수행
  • Join Condition을 따로 명시하지 않는다.
    • 사용 불가
  • FROM table1 NATURAL [INNER] JOIN table2
  • FROM table1 NATURAL LEFT [OUTER] JOIN table2
  • FROM table1 NATURAL RIGHT [OUTER] JOIN table2
  • FROM table1 NATURAL RULL [OUTER] JOIN table2
notion image
notion image

이번에는 Attribute 이름을 바꿈

notion image
  • 같은 이름의 Attribute가 두 쌍이 있음
notion image
notion image
  • 이 쿼리들과 같으므로, 결과는 Empty set

CROSS JOIN

두 Table의 Tuple Pair로 만들 수 있는 모든 조합(Cartesian Product)을 Result Table로 반환
  • Join Condition 사용 가능
  • Implicit CROSS JOIN: FROM table1, table2
  • Explicit CROSS JOIN: FROM table1 CROSS JOIN table2
notion image
notion image
notion image

CROSS JOIN @ MySQL

  • 표준과 약간 다름
  • MySQL은 CROSS JOIN == INNER JOIN == JOIN
  • CROSS JOIN에 ON(or USING)을 같이 쓰면, INNER JOIN으로 동작
  • INNER JOIN(or JOIN을 ON(or USING) 없이 사용하면, CROSS JOIN으로 동작

SELF JOIN

Table이 자기 자신에게 JOIN 하는 경우

JOIN을 사용한 예제

JOIN Example

  • ID가 1003인 부서에 속하는 임직원 중 리더를 제외한 부서원의 ID, 이름, 연봉을 알고 싶다.
notion image
  • ID가 2001인 프로젝트에 참여한 임직원들의 이름과 직군, 소속 부서 이름을 알고 싶다.
notion image

ORDER BY

조회 결과를 특정 Attribute 기준으로 정렬하여 가져오고 싶을 때 사용
  • Default 정렬 방식은 오름차순(ASC)
  • 오름차순 == ASC
  • 내림차순 == DESC

ORDER BY Example

  • 임직원들의 정보를 연봉 순서대로 정렬해서 알고 싶다.
notion image
notion image
notion image
notion image
notion image
notion image

Aggregate Function

여러 Tuple들의 정보를 요약해서 하나의 값으로 추출하는 함수
  • 대표적으로 COUNT, SUM, MAX, MIN, AVG 함수가 있음
  • 관심있는 Attribute에 사용된다. ex) AVG(salary), MAX(birth_date)
  • NULL 값들은 제외하고 요약 값을 추출한다.

Aggregate Function Example

  • 임직원 수를 알고 싶다.
notion image
notion image

position으로 바꿔도 같은 결과

notion image
notion image
  • == 중복을 제거하지 않고 개수를 센다는 뜻

dept_id로 바꾸면

notion image
notion image
  • NULL을 제외하고 개수를 센다.

따라서 Tuple의 개수를 얻고 싶다면 *를 써라.

notion image

Aggregate Function Example

  • 프로젝트 2002에 참여한 임직원 수와 최대 연봉, 최소 연봉, 평균 연봉을 알고 싶다.
notion image
notion image

GROUP BY

관심있는 Attribute 기준으로 그룹을 나눠서, 그룹별로 Aggregate Function을 적용하고 싶을 때 사용
  • Grouping Attribute(s): 그룹을 나누는 기준이 되는 Attribute
  • Grouping Attribute(s)에 NULL 값이 있을 때, NULL 값을 가지는 Tuple들끼리 묶인다.

GROUP BY Example

notion image
notion image

HAVING

Aggregate Function의 결과값을 바탕으로 그룹을 필터링하고 싶을 때 사용
  • GROUP BY와 함께 사용
  • HAVING 절에 명시된 조건을 만족하는 그룹만 결과에 포함됨

HAVING Example

  • 프로젝트 참여 인원이 7명 이상인 프로젝트들에 대해서 각 프로젝트에 참여한 임직원 수와 최대 연봉, 최소 연봉, 평균 연봉을 알고 싶다.
notion image
notion image

HAVING Example

  • 각 부서별 인원 수를 인원 수가 많은 순서대로 정렬해서 알고 싶다.
notion image
notion image
  • 각 부서별 - 성별 인원 수를 인원 수가 많은 순서대로 정렬해서 알고 싶다.
notion image
notion image

HAVING Example

  • 회사 전체 평균 연봉보다 평균 연봉이 적은 부서들의 평균 연봉을 알고 싶다.
notion image
notion image

HAVING Example

  • 각 프로젝트 별로 프로젝트에 참여한 90년대생들의 수와 이들의 평균 연봉을 알고 싶다.
notion image
notion image
notion image
notion image
  • 각 프로젝트 별로 참여 인원이 7명 이상인 프로젝트에 참여한 90년대생들의 수와 이들의 평균 연봉을 알고 싶다.
notion image
notion image

정리

SELECT attribute(s) or aggregate function(s)
FROM table(s)
[ WHERE condition(s) ]
[ GROUP BY group attribute(s) ]
[ HAVING group condition(s) ]
[ ORDER BY attribute(s) ]

개념적인 실행 순서

  1. SELECT attribute(s) or aggregate function(s)
 
  1. FROM table(s)
  1. [ WHERE condition(s) ]
  1. [ GROUP BY group attribute(s) ]
  1. [ HAVING group condition(s) ]
  1. [ ORDER BY attribute(s) ]

실제 실행 순서

💡
각 RDBMS에서 어떻게 구현했는지에 따라 다르다.

출처