SQL 함수로 결과에 순위 부여하기 | ROW_NUMBER, RANK, DENSE_RANK, NTILE
ROW_NUMBERROW_NUMBER는 모든 행에 유일값으로 순위를 부여한다. 조건에 따라 같은 순위에 놓일 수 있는 경우에는 정렬 순서에 따라 순위를 부여한다. 기본적인 사용 방법은 다음과 같다. PARTITION BY는 그룹별로 묶어주는 역할을 수행하며, ORDER BY로 순서도 부여할 수 있다. (물론 이 기능들을 사용하지 않을 수 있다.)ROW_NUMBER() OVER (PARTITION BY 열 ORDER BY 열)RANKRANK는 ROW_NUMBER와 유사하지만, 같은 순위를 같은 값을 부여한다. 그리고 그 다음 순위에 대해서는 같은 순위의 개수만큼 더해서 순위를 매긴다. 예를 들면, 공동 3순위가 3개가 존재하면 그 다음 순위는 6순위가 부여된다. 기본적인 사용 방법은 다음과 같다.RANK(..
2025.01.20
SQL
SQL 집계함수 응용 사례 정리하기 | 고유값 집계, 그룹별 집계, 부분합
집계함수의 경우 보다 직관적이라 기본적인 내용들보다는 실질적으로 활용할 수 있는 사례나 잘 몰랐던 내용 위주로 정리하였다.고유값 데이터 개수 세기COUNT와 DISTINCT 문을 조합하면 NULL 값이 아닌 고유값의 데이터 개수를 구할 수 있다. 아래는 활용 예시이다.SELECT COUNT(DISTINCT Country) FROM Customers;그룹별 집계하기GROUP BY와 조합하면 그룹별 합계, 평균, 최대, 최소 등을 구할 수 있다. 아래 예시는 sector로 그룹화해서 종가(close_price)의 합계, 평균, 최대 및 최소를 구하는 방법이다.SELECT sector, SUM(close_price), AVG(close_price), MAX(close_price), MIN(close_price..
2025.01.17
SQL
SQL 기본 날짜 함수 정리하기 | 날짜 정보 가져오기, 날짜 연산, 날짜 시간 형식 지정
날짜 정보 가져오기서버의 현재 날짜, 시간 반환하기현재 접속 중인 데이터베이스 서버의 시간을 확인하려면, SYSDATE를 사용할 수 있다. ("YYYY-MM-DD HH:MM:SS" 로 반환)SELECT SYSDATE();날짜의 개별 정보 가져오기날짜 형식의 일, 월, 연에 대한 정보를 가져오려면 직관적으로 DAY, MONTH, YEAR 함수를 사용할 수 있다. 사용법은 아래와 같다.SELECT DAY("2017-06-15");SELECT MONTH("2017-06-15");SELECT YEAR("2017-06-15");날짜 연산날짜 더하기날짜를 더하거나 빼려면 DATE_ADD를 사용한다. 다음은 주어진 날짜로부터 10일을 더한 것을 반환하는 예시이다.SELECT DATE_ADD("2017-06-15", ..
2025.01.16
SQL
SQL 기본 문자열 함수 정리하기
문자열 연결문자열과 문자열 연결문자열끼리 연결할 때는 단순히 +로 연결할 수도 있지만, CONCAT 함수를 사용할 수 있다. 다음은 몇몇 문자열을 한번에 연결한 예시이다.SELECT CONCAT("SQL ", "Tutorial ", "is ", "fun!") AS ConcatenatedString;만약 3개의 열을 하나의 열로 합치고 싶다면 아래 예제처럼 활용할 수 있다.SELECT CONCAT(Address, " ", PostalCode, " ", City) AS AddressFROM Customers;데이터 형 변환문자열과 다른 데이터형 연결문자열이 아닌 다른 데이터형의 값과 연결해야 할 경우는 어떻게 할 수 있을까? 다른 프로그래밍 언어처럼 변환하여 연결해주면 되는데, CAST와 CONVERT를 활..
2025.01.15
SQL
SQL 여러 쿼리 연결하기 | UNION, INTERSECT, EXCEPT
UNIONUNION은 두개 이상의 쿼리 결과를 결합하는데 사용된다. 모든 SELECT문은 같은 숫자의 열을 가져야 하고, 유사한 데이터 형식이어야 하며, 같은 순서로 열이 구성되어야 한다. 기본적인 형식은 다음과 같다.SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2;UNION은 기본적으로 중복을 제거한다. 만약 중복된 것까지 포함하고 싶다면 UNION ALL을 사용하자.SELECT column_name(s) FROM table1UNION ALLSELECT column_name(s) FROM table2;INTERSECTINTERSECT는 이름처럼 교집합이기 때문에 INNER JOIN과 유사하나, 각 쿼리에서 반환한 결과에서 ..
2025.01.12
SQL
공통 테이블식 쿼리(CTE) 기본 내용 정리하기 | 일반 & 재귀 CTE
공통 테이블 식(Common Table Expression, CTE)은 데이터베이스에 없는 테이블이 필요할 때 사용한다. CTE는 크게 일반 CTE와 재귀 CTE로 나뉜다. 일반 CTE일반 CTE는 여러 쿼리들을 결합할 때 사용할 수 있다. 기본적인 형식은 다음과 같다. WITH [CTE 테이블] (열1, 열2 ...)AS( )SELECT [열 이름] FROM [CTE_테이블]위 쿼리는 AS 안에 있는 SELECT문으로 반환하는 열을 가지고 CTE 테이블을 정의한다. 만약 가져오는 SELECT문과 CTE 테이블의 열 개수가 다르면 오류가 반환된다.재귀 CTE재귀 CTE는 CTE 결과를 CTE 내부 쿼리에서 재사용하는 구조이다. 이는 주로 계층이나 그래프 형태의 데이터를 검색할 때 많이 사용한다고 한..
2025.01.11
SQL
SQL 서브 쿼리 사용하기 | IN, ANY, ALL, EXISTS
서브쿼리(subquery)는 쿼리 안에 포함되는 또 다른 쿼리이다. 조인하지 않고 다른 테이블과 일치하는 행을 찾거나, 조인 결과를 다시 조인할 수 있다. 서브쿼리의 주요 특징은 다음과 같다.- 반드시 소괄호로 감싸 사용- 주 쿼리를 실행하기 전에 1번만 실행- 비교 연산자에 서브쿼리를 사용하는 경우 서브쿼리를 오른쪽에 기술- 내부에는 ORDER BY 사용 불가WHERE 서브쿼리WHERE문에 사용하는 서브 쿼리를 중첩 서브쿼리(nested subquery)라고도 한다. 이를 조건문의 일부로 사용할 수 있다. 단일 행서브쿼리의 결과가 1행만 반환되는 경우이다. 다음은 쿼리 기본 형식이다.SELECT [열 이름]FROM [테이블]WHERE [열] = (SELECT [열] FROM [테이블] WHERE [조건..
2025.01.10
SQL
no image
SQL로 서로 다른 테이블 조합(JOIN)하기 | INNER JOIN, OUTER JOIN, CROSS JOIN, SELF JOIN
INNER JOIN내부 조인(Inner Join)은 키에 해당하는 각 테이블의 열 값을 비교해 조건에 맞는 값을 검색한다. 기초 교육 과정에서 배운 집합의 관점에서 살펴본다면, 두개의 서로 다른 집합(테이블)의 교집합이라고 생각할 수 있다. 다음은 내부 조인의 기본 형식이다.SELECT [열]FROM [테이블1]INNER JOIN [테이블2] ON [테이블1.열] = [테이블2.열]WHERE [검색 조건] 여기서 ON문은 조인 조건으로 활용된다. WHERE와의 차이점은 ON은 조인을 수행할 때 조건으로 사용되는 것이고, WHERE는 조인을 완료한 상태에서 데이터를 조회할 때 사용한다. 만약 서로 다른 3개 이상의 테이블을 조인한다면 아래처럼 INNER JOIN을 추가하는 방식으로 가능하다.SELECT [..
2025.01.09
SQL
SQL로 테이블 생성 및 조작하기 정리 | CREATE, INSERT, UPDATE, DELETE
데이터베이스 다루기SELECT, INSERT, UPDATE, DELETE 등 데이터 조작 언어(Data Manipulation Language, DML)는 테이블을 대상으로 한다. 따라서 이러한 구문을 사용하기 위한 테이블을 생성(CREATE), 변경(ALTER), 삭제(DROP)하는 기능이 필요한데, 이를 데이터 정의 언어(Data Definition Language)라고 한다. 데이터베이스 생성 및 삭제데이터베이스 생성하기 위한 기본 형식은 다음과 같다.CREATE DATABASE [데이터베이스 이름]데이터베이스를 삭제하기 위한 기본 형식은 다음과 같다.DROP DATABASE [데이터베이스 이름]테이블 다루기테이블은 데이터베이스의 내부에 있는 개념으로 다루기 위해서는 데이터베이스를 먼저 선택해야 한..
2025.01.06
SQL
반응형

ROW_NUMBER

ROW_NUMBER는 모든 행에 유일값으로 순위를 부여한다. 조건에 따라 같은 순위에 놓일 수 있는 경우에는 정렬 순서에 따라 순위를 부여한다. 기본적인 사용 방법은 다음과 같다. PARTITION BY는 그룹별로 묶어주는 역할을 수행하며, ORDER BY로 순서도 부여할 수 있다. (물론 이 기능들을 사용하지 않을 수 있다.)

ROW_NUMBER() OVER (PARTITION BY 열 ORDER BY 열)

RANK

RANK는 ROW_NUMBER와 유사하지만, 같은 순위를 같은 값을 부여한다. 그리고 그 다음 순위에 대해서는 같은 순위의 개수만큼 더해서 순위를 매긴다. 예를 들면, 공동 3순위가 3개가 존재하면 그 다음 순위는 6순위가 부여된다. 기본적인 사용 방법은 다음과 같다.

RANK() OVER (PARTITION BY 열 ORDER BY 열)

DENSE_RANK

RANK에서 같은 순위에 대해서 개수를 고려했지만, 개수를 고려하고 싶지 않다면 DENSE_RANK를 사용하면 된다. 기본적인 사용 방법은 다음과 같다.

DENSE_RANK() OVER (PARTITION BY 열 ORDER BY 열)

NTILE

지정한 값만큼 데이터 행을 그룹화해 그룹별 순위를 매기고 싶다면 NTILE을 사용한다. 기본적인 사용 방법은 다음과 같다.

NTILE(정수 숫자) OVER (PARTITION BY 열 ORDER BY 열)

PERCENT_RANK

앞서 순위 계산하는 여러 방법(ROW_NUMBER, RANK 등)을 공유하였다. 여기서는 상대 순위를 계산하기 위해 PERCENT_RANK를 사용하였다. 기본적인 사용법은 다음과 같다.

PERCENT_RANK() OVER (PARTITION BY 열 ORDER BY 열)

참고자료

  1. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
반응형
반응형

집계함수의 경우 보다 직관적이라 기본적인 내용들보다는 실질적으로 활용할 수 있는 사례나 잘 몰랐던 내용 위주로 정리하였다.

고유값 데이터 개수 세기

COUNT와 DISTINCT 문을 조합하면 NULL 값이 아닌 고유값의 데이터 개수를 구할 수 있다. 아래는 활용 예시이다.

SELECT COUNT(DISTINCT Country) FROM Customers;

그룹별 집계하기

GROUP BY와 조합하면 그룹별 합계, 평균, 최대, 최소 등을 구할 수 있다. 아래 예시는 sector로 그룹화해서 종가(close_price)의 합계, 평균, 최대 및 최소를 구하는 방법이다.

SELECT sector, SUM(close_price), AVG(close_price), MAX(close_price), MIN(close_price) 
FROM nasdaq
GROUP BY sector

부분합 구하기

부분합을 구하려면 GROUP BY와 ROLLUP를 조합한다. 아래는 모든 연도 값에 대한 총계를 보여주는 부분합을 보여주는 쿼리이다.

SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP;
반응형
반응형

날짜 정보 가져오기

서버의 현재 날짜, 시간 반환하기

현재 접속 중인 데이터베이스 서버의 시간을 확인하려면, SYSDATE를 사용할 수 있다. ("YYYY-MM-DD HH:MM:SS" 로 반환)

SELECT SYSDATE();

날짜의 개별 정보 가져오기

날짜 형식의 일, 월, 연에 대한 정보를 가져오려면 직관적으로 DAY, MONTH, YEAR 함수를 사용할 수 있다. 사용법은 아래와 같다.

SELECT DAY("2017-06-15");
SELECT MONTH("2017-06-15");
SELECT YEAR("2017-06-15");

날짜 연산

날짜 더하기

날짜를 더하거나 빼려면 DATE_ADD를 사용한다. 다음은 주어진 날짜로부터 10일을 더한 것을 반환하는 예시이다.

SELECT DATE_ADD("2017-06-15", INTERVAL 10 DAY)

여기서 단위는 아래의 것들이 사용가능하다. (더 다양하지만, 기본적인 것들만 정리)

  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • QUARTER
  • YEAR

날짜 차이 구하기

만약 두 날짜 간 차이를 구하려면 DATEDIFF를 사용할 수 있다. 사용법은 다음과 같다.

SELECT DATEDIFF("2017-06-25", "2017-06-15");

시간, 날짜 자료형 지정하기

시간 자료형

시간 자료형을 지정하기 위해서는 TIME_FORMAT을 사용할 수 있다. 주요한 포맷은 다음과 같다.

Format Description
%H 시간 (00~23)
%h 시간 (00~12)
%i 분 (00~59)
%p AM 또는 PM
%r hh:mm:ss AM/PM
%T hh:mm:ss

아래는 한 예시이다. (결과 : 07 30 10 PM)

SELECT TIME_FORMAT("19:30:10", "%h %i %s %p");

날짜 자료형

날짜 자료형을 지정하기 위해서는 DATE_FORMAT을 사용할 수 있다. 몇 개의 사례를 살펴보면서 익숙해지자. 연도는 네자리, 월은 영문으로, 일은 숫자로 나타내는 쿼리이다. (결과는 June 15 2017)

SELECT DATE_FORMAT("2017-06-15", "%M %d %Y");

만약 영문으로 전체 요일까지 표시하고 싶다면 아래와 같이 적용이 가능하다. (결과는 Thursday June 15 2017)

SELECT DATE_FORMAT("2017-06-15", "%W %M %d %Y");

참고자료

  1. W3 School
  2. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
반응형
반응형

문자열 연결

문자열과 문자열 연결

문자열끼리 연결할 때는 단순히 +로 연결할 수도 있지만, CONCAT 함수를 사용할 수 있다. 다음은 몇몇 문자열을 한번에 연결한 예시이다.

SELECT CONCAT("SQL ", "Tutorial ", "is ", "fun!") AS ConcatenatedString;

만약 3개의 열을 하나의 열로 합치고 싶다면 아래 예제처럼 활용할 수 있다.

SELECT CONCAT(Address, " ", PostalCode, " ", City) AS Address
FROM Customers;

데이터 형 변환

문자열과 다른 데이터형 연결

문자열이 아닌 다른 데이터형의 값과 연결해야 할 경우는 어떻게 할 수 있을까? 다른 프로그래밍 언어처럼 변환하여 연결해주면 되는데, CAST와 CONVERT를 활용하면 된다. CAST 함수의 사용법은 다음과 같다.

CAST(value AS datatype)

-- Example

SELECT CAST("2017-08-29" AS DATE);

CONVERT() 함수는 특정 값을 데이터타입이나 문자열의 집합으로 바꿔준다. 아래는 사용법 예시이다.

CONVERT(value, type)

-- Or

CONVERT(value USING charset)

-- Example

SELECT CONVERT(150, CHAR);

NULL 처리하기

특정 데이터형이 아닌 NULL과 연결하려고 하면, ISNULL로 대체할 값을 만든 후 반환한다. 다음은 ISNULL의 사용법이다. 만약 NULL 값이 있는 경우 공백으로 반환할 수 있다.

ISNULL(column, expression)   

-- Example
SELECT ISNULL(col_a, "");

만약 여러 열에 대해서 NULL을 체크하고 대입하고 싶다면, COALESCE 함수를 사용할 수 있다. 여러 개의 데이터 리스트를 넣고 그 중에 가장 첫번째로 NULL이 아닌 것을 입력한다. 사용법은 아래와 같이 넣어줄 수 있다.

COALESCE(val1, val2, ...., val_n)

문자열 처리

소문자, 대문자 변경

소문자와 대문자를 구분하는 경우도 있지만, 구분이 필요하지 않을 수도 있다. 이때 LOWER와 UPPER를 사용하면 된다.

SELECT LOWER("SQL Tutorial is FUN!");
SELECT UPPER("SQL Tutorial is FUN!");

문자열 공백 제거

문자열 특성상 공백이 입력되는 경우가 있다. 이 경우 TRIM을 활용하면 되는데, 다른 프로그래밍 언어처럼 왼쪽, 오른쪽에 대해서도 적용할 수 있는 LTRIM, RTRIM도 존재한다. 어떤 공백을 제거하는지 살펴보기 위해 아래 예제를 참고하면 된다.

SELECT TRIM('    SQL Tutorial    ') AS TrimmedString;
SELECT RTRIM("SQL Tutorial     ") AS RightTrimmedString;
SELECT LTRIM("     SQL Tutorial") AS LeftTrimmedString;

지정한 길이만큼 반환

앞서 TRIM처럼 왼쪽이나 오른쪽에서 지정한 길이만큼 반환하는 함수가 LEFT, RIGHT가 있다. 사용법은 아래와 같다.

RIGHT(string, number_of_chars)
LEFT(string, number_of_chars)

만약 지정한 범위의 문자열을 반환하려면 SUBSTRING을 활용할 수 있다. string부터 시작 숫자를 그리고 반환할 문자 개수를 적어서 사용한다.

SUBSTRING(string, start, length)

--OR

SUBSTRING(string FROM start FOR length)

문자 바꾸기

기존 문자에서 특정 문자(substring)를 새로운 문자(new_string)으로 바꾸기 위해서는 아래와 같이 REPLACE를 쓰면 된다.

REPLACE(string, substring, new_string)

반복하기

특정 문자를 반복하려면 REPEAT을 사용하면 된다.

REPEAT(string, number)

만약 공백을 반복하고 싶다면, SPACE를 활용한다.

SPACE(number)

역순

만약 문자열을 거꾸로 정렬하기 위해서는 REVERSE를 활용한다.

REVERSE(string)

참고자료

  1. W3Schools
  2. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
반응형
반응형

UNION

UNION은 두개 이상의 쿼리 결과를 결합하는데 사용된다. 모든 SELECT문은 같은 숫자의 열을 가져야 하고, 유사한 데이터 형식이어야 하며, 같은 순서로 열이 구성되어야 한다. 기본적인 형식은 다음과 같다.

SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

UNION은 기본적으로 중복을 제거한다. 만약 중복된 것까지 포함하고 싶다면 UNION ALL을 사용하자.

SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

INTERSECT

INTERSECT는 이름처럼 교집합이기 때문에 INNER JOIN과 유사하나, 각 쿼리에서 반환한 결과에서 중복을 제외한다. 기본적인 형식은 다음과 같다.

SELECT column_name(s) FROM table1
INTERSECT
SELECT column_name(s) FROM table2;

EXCEPT

EXCEPT는 한 쿼리(A)에는 있지만 다른 쿼리(B)에는 없는 것을 반환한다. 위와 동일하게 중복값은 제외한다. 기본적인 형식은 다음과 같다.

SELECT column_name(s) FROM table1
EXCEPT
SELECT column_name(s) FROM table2;

전체 정리

위 내용들을 일반화하면 아래와 같이 정리할 수 있다.

query_block [set_op query_block] [set_op query_block] ...

query_block:
    SELECT | TABLE | VALUES

set_op:
    UNION | INTERSECT | EXCEPT

참고자료

  1. W3 School Tutorial
  2. MySQL Documentation
반응형
반응형

공통 테이블 식(Common Table Expression, CTE)은 데이터베이스에 없는 테이블이 필요할 때 사용한다. CTE는 크게 일반 CTE와 재귀 CTE로 나뉜다.

일반 CTE

일반 CTE는 여러 쿼리들을 결합할 때 사용할 수 있다. 기본적인 형식은 다음과 같다.

WITH [CTE 테이블] (열1, 열2 ...)
AS
(
    <SELECT 문>
)
SELECT [열 이름] FROM [CTE_테이블]

위 쿼리는 AS 안에 있는 SELECT문으로 반환하는 열을 가지고 CTE 테이블을 정의한다. 만약 가져오는 SELECT문과 CTE 테이블의 열 개수가 다르면 오류가 반환된다.

재귀 CTE

재귀 CTE는 CTE 결과를 CTE 내부 쿼리에서 재사용하는 구조이다. 이는 주로 계층이나 그래프 형태의 데이터를 검색할 때 많이 사용한다고 한다. 기본적인 형식은 다음과 같다.

WITH [CTE 테이블] (열1, 열2 ...)
AS
(
    <SELECT * FROM 테이블 A> -- 쿼리 1
    UNION ALL
    <SELECT * FROM 테이블 B JOIN CTE_테이블> -- 쿼리 2
)
SELECT [열 이름] FROM [CTE_테이블]

위 구조에서 쿼리1은 앵커 멤버, 쿼리 2는 재귀 멤버라고 한다. 앵커 멤버는 자기 자신 CTE를 참조하지 않고 재귀 멤버 앞에 위치해 재귀 쿼리의 시작을 정의한다. 재귀 멤버는 앵커 멤버의 결과를 기반으로 반복적으로 호출되는 쿼리이다. 동작하는 방식은 다음과 같다.


  1. 쿼리 1을 실행한다. 쿼리 2의 기본값은 0으로 초기화된다.
  2. 쿼리 2를 실행한다. 쿼리 2의 기본값은 1만큼 증가한다. 쿼리 1의 결과 행 수만큼 쿼리 2에서 CTE 테이블을 재귀 호출하고, 쿼리 2 기본값이 1씩 증가하면서 쿼리 1의 결과 행 수까지 도달하면 재귀호출을 중단한다.
  3. 외부 SELECT문에서 1,2 과정을 통해 만든 CTE 결과를 탐색한다.

참고자료

  1. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
반응형
반응형

서브쿼리(subquery)는 쿼리 안에 포함되는 또 다른 쿼리이다. 조인하지 않고 다른 테이블과 일치하는 행을 찾거나, 조인 결과를 다시 조인할 수 있다. 서브쿼리의 주요 특징은 다음과 같다.


- 반드시 소괄호로 감싸 사용
- 주 쿼리를 실행하기 전에 1번만 실행
- 비교 연산자에 서브쿼리를 사용하는 경우 서브쿼리를 오른쪽에 기술
- 내부에는 ORDER BY 사용 불가

WHERE 서브쿼리

WHERE문에 사용하는 서브 쿼리를 중첩 서브쿼리(nested subquery)라고도 한다. 이를 조건문의 일부로 사용할 수 있다.

단일 행

서브쿼리의 결과가 1행만 반환되는 경우이다. 다음은 쿼리 기본 형식이다.

SELECT [열 이름]
FROM [테이블]
WHERE [열] = (SELECT [열] FROM [테이블] WHERE [조건])

주의할 점은 비교 연산자를 사용할 때는 반드시 단일 행 케이스여야 한다. 즉, 가장 바깥의 WHERE에 =,<,> 등을 사용하려면 하나 이하의 결과만 반환해야 오류 없이 동작한다. 만약 반환 결과가 여러 개가 필요하면 IN, ANY, ExISTS, ALL을 사용할 수 있다.

IN

IN은 앞서 설명한 것처럼 OR 대신 사용할 수 있다. 기본 형식은 다음과 같이 사용할 수 있다.

SELECT [열 이름]
FROM [테이블]
WHERE [열] IN (SELECT [열] FROM [테이블] WHERE [조건])

ANY

ANY는 하나라도 만족하는 조건을 검색한다. 기본 형식은 다음과 같이 사용할 수 있다.

SELECT column_name(s)
FROM table_name
WHERE column_name operator ANY
  (SELECT column_name
  FROM table_name
  WHERE condition);

ALL

ALL은 ANY와 다르게 모든 것을 만족하는 것을 검색한다. 기본 형식은 다음과 같이 사용할 수 있다.

SELECT column_name(s)
FROM table_name
WHERE column_name operator ALL
  (SELECT column_name
  FROM table_name
  WHERE condition);

EXISTS

EXISTS는 조건의 결과가 있는지 없는지를 확인해 1개라도 있으면 TRUE, 없으면 FALSE를 반환한다. 기본 형식은 다음과 같이 사용할 수 있다.

SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);

만약 결과가 없다면 FALSE이므로 위 쿼리는 아무것도 반환하지 않는다. 이를 반대로 적용하려면 EXISTS 앞에 NOT만 붙여준다.

FROM 서브쿼리

FROM 문에서는 보통 조인을 많이 활용하기 때문에 이와 결합해서 사용한다. 조인인 대상에 별도의 필터링서브쿼리 결과)을 수행하는 것으로 이해된다. 기본 형식은 다음과 같이 사용할 수 있다.(inline view라고도 함)

SELECT [열 이름]
FROM [테이블] AS a
    INNER JOIN (SELECT [열] FROM [테이블] WHERE [조건]) AS b ON a.key = b.key
WHERE [조건]

참고자료

  1. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
  2. W3 Schools MySQL Tutorial
반응형
반응형

INNER JOIN

내부 조인(Inner Join)은 키에 해당하는 각 테이블의 열 값을 비교해 조건에 맞는 값을 검색한다. 기초 교육 과정에서 배운 집합의 관점에서 살펴본다면, 두개의 서로 다른 집합(테이블)의 교집합이라고 생각할 수 있다. 다음은 내부 조인의 기본 형식이다.

SELECT [열]
FROM [테이블1]
INNER JOIN [테이블2] ON [테이블1.열] = [테이블2.열]
WHERE [검색 조건]

 

여기서 ON문은 조인 조건으로 활용된다. WHERE와의 차이점은 ON은 조인을 수행할 때 조건으로 사용되는 것이고, WHERE는 조인을 완료한 상태에서 데이터를 조회할 때 사용한다.

 

만약 서로 다른 3개 이상의 테이블을 조인한다면 아래처럼 INNER JOIN을 추가하는 방식으로 가능하다.

SELECT [열]
FROM [테이블1]
INNER JOIN [테이블2] ON [테이블1.열] = [테이블2.열]
INNER JOIN [테이블3] ON [테이블2.열] = [테이블3.열]
WHERE [검색 조건]

예시

아래는 industry_group 테이블에서 industry가 automobile인 그룹의 열들을 조회하는 쿼리이다. 테이블 간 열 이름이 같을 수 있고, 이로 인해 쿼리가 제대로 동작하지 않거나 불필요하게 쿼리가 길어질 수 있으므로 테이블에 별칭을 AS로 지정하였다.

SELECT 
    a.industry
    c.symbol
    c.company_name
    c.ipo_year
    c.sector   
FROM industry_group AS a
    INNER JOIN industry_group_symbol AS b ON a.num = b.num
    INNER JOIN nasdaq_company AS c ON b.symbol = c.symbol
WHERE a.industry = N'automobile'

OUTER JOIN

외부 조인(OUTER JOIN)은 일치 항목을 고려하지 않고, 한쪽 테이블을 다른 쪽 테이블에 조합할 때 사용한다. 아래는 외부 조인의 기본 형식이다. 여기서 < >로 감싼 항목은 1개만 선택해야 한다는 뜻이다.

SELECT [열]
FROM [테이블1]
<LEFT, RIGHT, FULL> OUTER JOIN [테이블2] ON [테이블1.열] = [테이블2.열]
WHERE [검색 조건]

LEFT & RIGHT OUTER JOIN (교집합 포함)

위 기본 형식은 다소 추상적이기에 좀 더 구체적인 쿼리를 살펴보자. LEFT와 RIGHT는 두개의 테이블 중 어느 것을 선택하느냐의 문제이다. SELECT의 대상이 되는 테이블(A)은 왼쪽, 그게 아닌 경우는 다른 테이블(B)로 가정한다. LEFT OUTER JOIN을 하면 우선 A를 모두 포함한다. 그 다음 A와 B의 Key 값을 비교해 교집합 부분을 제외하고서는 NULL 처리를 한다. 이를 쿼리로 나타내면 다음과 같다.

SELECT [열]
FROM A
LEFT OUTER JOIN B ON A.Key = B.Key

LEFT & RIGHT OUTER JOIN (교집합 제외)

위에서 진행한 것에서 교집합 부분을 제외하고 싶다면, 아래와 같이 쿼리를 작성할 수 있다. 만약 SELECT FROM 테이블 대상(A)이 아닌 B 테이블에 진행하고 싶다면 LEFT를 RIGHT로만 바꿔주면 된다.

SELECT [열]
FROM A
LEFT OUTER JOIN B ON B.Key IS NULL

FULL OUTER JOIN

FULL OUTER JOIN은 LEFT OUTER JOIN과 RIGHT OUTER JOIN을 각각 수행한 것이다. 위에서 공부한 두가지를 섞어 보면 교집합 포함 케이스는 집합에서 합집합으로 나타날 것이다.

SELECT [열]
FROM A
FULL OUTER JOIN B ON A.Key = B.Key

만약 교집합은 제외하면 합집합에서 교집합만 뺀 것으로 나타나는데, 이를 쿼리로 표현하면 다음과 같다.

SELECT [열]
FROM A
FULL OUTER JOIN B ON B.Key IS NULL

다만, FULL OUTER JOIN은 많이는 사용하지 않는다고 하는데, 전체에서 데이터의 누락이나 오류가 있을 때 사용한다고 한다. 다음은 그런 예시이다. 2개의 테이블(A, B)에서 symbol 열의 NULL 값을 필터링하는 쿼리다.

SELECT 
    A.symbol
    B.symbol
FROM A
    FULL OUTER JOIN B ON A.symbol = B.symbol
WHERE A.symbol IS NULL OR B.symbol IS NULL

CROSS JOIN

교차 조인(CROSS JOIN)은 각 테이블의 모든 경우의 수를 조합할 때 사용한다. 교차 조인은 테이블1,2의 데이터를 모두 조합해 샘플 데이터를 만들 때 활용할 수 있다. 다음은 교차 조인의 기본 형식이다.

SELECT [열]
FROM [테이블 1]
    CROSS JOIN [테이블 2]
WHERE [검색 조건]

SELF JOIN

셀프 조인(SELF JOIN)은 테이블 자기 자신을 조인에 활용하는 것이다.

 

아래 이미지는 JOIN에 관해 시각적으로 잘 이해될 수 있는 이미지다. 잘 참고해서 JOIN을 이해하자.

JOIN 이미지[2]

 

참고자료

  1. 강성욱. Do it! SQL 입문. 이지스 퍼블리싱.
  2. https://stackoverflow.com/questions/53949197/isnt-sql-a-left-join-b-just-a
반응형
반응형

데이터베이스 다루기

SELECT, INSERT, UPDATE, DELETE 등 데이터 조작 언어(Data Manipulation Language, DML)는 테이블을 대상으로 한다. 따라서 이러한 구문을 사용하기 위한 테이블을 생성(CREATE), 변경(ALTER), 삭제(DROP)하는 기능이 필요한데, 이를 데이터 정의 언어(Data Definition Language)라고 한다.

데이터베이스 생성 및 삭제

데이터베이스 생성하기 위한 기본 형식은 다음과 같다.

CREATE DATABASE [데이터베이스 이름]

데이터베이스를 삭제하기 위한 기본 형식은 다음과 같다.

DROP DATABASE [데이터베이스 이름]

테이블 다루기

테이블은 데이터베이스의 내부에 있는 개념으로 다루기 위해서는 데이터베이스를 먼저 선택해야 한다.

USE [데이터베이스 이름]

테이블 생성 및 삭제

테이블을 생성하기 위한 기본 형식은 다음과 같다.

CREATE TABLE [테이블 이름] (
열1 자료형,
열2 자료형,
...
)

테이블을 삭제하기 위한 기본 형식은 다음과 같다. 만약 다른 테이블과 종속관계이면서 부모테이블인 경우 삭제가 되지 않는 경우가 있다면, 종속관계를 제거한 뒤 자식테이블을 삭제한 후에야 부모테이블을 삭제할 수 있다.

DROP TABLE [테이블 이름]

만약 NULL을 허용하지 않는 테이블을 만들기 위해서는 아래와 같이 자료형 이후에 NOT NULL을 넣어서 쿼리를 작성하면 된다.

CREATE TABLE [테이블 이름] (
열1 자료형 NOT NULL

데이터 삽입, 수정, 삭제하기

데이터를 삽입하기 위한 기본 형식은 다음과 같다. 열 이름을 생략해서도 가능한데, 이를 위해서는 테이블의 열 순서와 개수에 맞춰서 데이터를 채워줘야 한다.

INSERT INTO 테이블 (열1, 열2, ...) VALUES (값1, 값2, ...)

테이블에 삽입된 데이터를 수정하려면 UPDATE를 다음과 같이 사용한다. 여기서 WHERE문은 생략할 수 있으나, 이 경우 테이블 전체 데이터를 수정하기 때문에 주의가 필요하다.

UPDATE [테이블 이름] SET 열1 = 값1, 열2 = 값2, ...
WHERE [열] = [조건]

입력된 데이터를 삭제하려면 DELETE를 사용하는데, 사용법은 UPDATE와 거의 유사하다. 여기서도 WHERE은 생략 가능하나, 이 경우 테이블 전체 데이터를 수정하게 된다.

DELETE [테이블 이름] 

외래키 연결의 경우

앞서 테이블의 삭제 부분에서 테이블이 종속관계에 있으면 삭제가 제대로 되지 않는다고 언급한 바 있다. 이는 관계형 데이터베이스 구축의 기본으로 부모 테이블의 기본키를 참조하는 외래키를 추가할 수 있다.

ADD FOREIGN KEY (열1) REFERENCES 테이블 이름(열1)

이렇게 연결된 경우 자식 테이블에 데이터를 바로 입력/삭제하려고 하면 실패를 하게 된다. 이를 방지하기 위해 부모 테이블에 데이터를 입력/삭제하고 같은 데이터를 자식 테이블에 입력하는 방식으로 데이터를 입력/삭제할 수 있다.

-- 입력
INSERT INTO 부모테이블 VALUES (1)
INSERT INTO 자식테이블 VALUES (1)

-- 삭제
DELETE 자식테이블 WHERE 열1 = 1
DELETE 부모테이블 WHERE 열1 = 1

다른 테이블에 검색 결과 입력

기존 테이블에서 검색한 결과를 다른(대상) 테이블에 입력해서 데이터를 옮기고 싶을 수 있다. 예를 들어, 필요한 데이터만 따로 발췌해서 기존 테이블에 합치는 것과 같은 작업을 수행하는 것이다. 이를 위해서는 아래와 같은 구조로 옮겨줄 수 있다.

INSERT 대상 테이블
SELECT 열 FROM 기존 테이블
WHERE 조건문

새 테이블에 검색 결과 입력

위와 비슷하지만, 검색 결과를 저장하기 위해 새로운 테이블에 저장하는 방법이다. 이는 테이블의 데이터를 복사할 때 사용하면 유용할 것이다. 방법은 아래와 같이 쿼리를 작성하면 된다.

SELECT 열 INTO 새 테이블 FROM 기존 테이블
WHERE 조건문
반응형