이 문서는 SQL 표준 문법을 기본 기준으로 설명하며, 예시 DBMS별(예: MySQL, PostgreSQL, SQLite, Oracle, SQL Server 등) 동작 차이가 있을 수 있습니다.
🗂 목차
- 기본 작성 방법
- 1. SELECT … FROM
- 2. SELECT * FROM
- 3. WHERE (필터링)
- 4. BETWEEN, LIKE
- 5. ORDER BY (정렬)
- 6. COUNT (집계)
- 7. SUM·AVG·MIN·MAX (집계)
- 8. GROUP BY
- 9. HAVING
- 10. AS (별칭)
- 11. CASE WHEN
- 12. JOIN
- 13. UNION
- 14. SubQuery
기본 작성 방법
1. 명확하게 조건을 작성하기
- 정확하게 어디에서, 어떤 데이터를 검색해야 하는지 명확하게 전달하기
1. 데이터베이스.테이블명 - 어디 데이터베이스에서 어떤 테이블을 검색할 지
ex) emp.employee
2. 테이블명.컬럼명 - 어디 테이블의 어떤 컬럼명을 검색할 지
ex) employee.salary
2. 띄어쓰기
- SQL 구문 작성 중 공백 r갯수는 중요하지 않음
- 키워드 간 최소 한 칸 필요. 줄바꿈·여러 칸 공백은 무관
- [SELECT * FROM] = [SELECT * FROM]
- 하나의 단어는 공백 없이 작성 - TOTAL_USER (TOTAL USER - X)
3. SQL 문장 마무리하기
- ;
- SQL 문장의 ‘종료’ 지정하는 기호
- 문장을 종료하지 않거나 실행 범위 지정하지 않고 실행 시 → 오류 발생
4. 대소문자 구분
- ' ' 작은 따옴표로 문자를 묶을 경우(주로 테이블이나 컬럼 명이 아닌 변수의 값을 사용하는 경우)에는 대소문자 구분 필요
- ‘MARKETING’ ≠ ‘Marketing’
- ex) EMP.DEPARTMENT = 'Marketing'
- ' ' 따옴표가 없는 변수의 경우에는 구분 X
5. AS(별칭)
- 컬럼명을 다른 이름으로 변경하기 위해서 사용
- 셀프 조인 시 하나의 컬럼을 다르게 표시할 때도 사용
6. SQL 실행하기
- 드래그 후 실행버튼
- 드래그 후 Ctrl+Enter(실행 환경에 따라 안 되는 경우도 있음)
1. SELECT FROM
SELECT 출력하고싶은 결과(column 등)
FROM 테이블이름(Table)
- 대소문자 구분X(문자열은 구분해야 함)
- 엔터 상관 X
- 괄호, 콤마(,) 사용 가능
2. SELECT * FROM
SELECT *
FROM 테이블이름
- 테이블 모든 열 출력하고 싶을 때(열 이름, 데이터 상태 확인 할 때)
- LIMIT과 함께 사용(상위 n개 행)
3. WHERE (필터링)
SELECT 출력하고싶은 결과
FROM 테이블 이름
WHERE 조건문(EX. 나라 = '멕시코')
- 조건은 여러 개를 동시에 설정할 수 있음
- 정수는 그대로, 문자는 따옴표 ' ' 사용
1. AND - 두 개 이상의 조건
WHERE 나라 = ‘멕시코’ AND 나이 = 30
2. OR - 여러 조건 중 하나
WHERE 나라 = ‘멕시코’ OR 나이 = 30
3. !=(<>) - 제외하고 싶은 필터
WHERE 나라 != ‘멕시코’
4. 크다, 작다, 크거나 작다, 작거나 같다
- >, <, >=, <=
WHERE age>20 and age<=29
5. 같은 열을 이용한 여러 조건은 in/not in과 리스트 활용
WHERE country in ('korea', 'japan', 'usa')
4. BETWEEN, LIKE
BETWEEN
--30대 출력
WHERE 나이 BETWEEN 30 AND 39
--30대 제외 출력
WHERE 나이 NOT BETWEEN 30 AND 39
- 범위를 나타낼 때 WHERE 절보다 더 직관적이고 간편함
- BETWEEN - 범위를 나타낼 때
- 양 끝점(30, 39) 모두 포함함
- WHERE 나이 >= 30 AND 나이 <=39
- → WHERE 나이 BETWEEN 30 AND 39
- NOT BETWEEN - 제외하고 싶은 범위
- 양 끝점(30,39)은 제외된다.
- 문자열과 날짜도 사용가능
LIKE(패턴 연산자)
-- 이름이 Tom으로 시작하는 사람 출력
WHERE 이름 LIKE 'TOM%'
-- 이름이 y로 끝나지 않는 사람 출력
WHERE 이름 NOT LIKE '%y'
-- 이름에 or이 어디든 들어있는 사람
WHERE 이름 LIKE '%OR%'
- 일정 패턴을 찾을 때
- 대소문자 구분 없이 모두 탐색 가능
- MySQL에서는 LIKE 기본이 대소문자 구분이 없지만, PostgreSQL 등 일부 DB에서는 구분함
- 패턴 매칭 목록
- ‘A%’ - A로 시작
- ‘%A’ - A로 끝
- ‘%A%’ - A가 들어가는
- ‘A%B’ - A로 시작, B로 끝나는
- ‘A__R_’ - 첫 글자 A, 4번째 글자 R
- ‘A__%’ - A로 시작하고 3글자 이상
- ‘_A%’ - 두 번째 글자 A
- ‘AL’ - 정확히 'AL' 일치하는 경우
- _,% - 와일드카드라고 지칭
5. ORDER BY(정렬)
SELECT 출력하고 싶은 결과
FROM 테이블 이름
WHERE 조건문
ORDER BY 열 이름 ASC(DESC)
- 오름차순 - 열이름 ASC
- 내림차순 - 열이름 DESC
- 기본값 - ASC
- 여러 개의 열이름 이용해 정렬 - 콤마로 구분
ORDER BY 고객 가입일 DESC, 고객이름 ASC
- 고객 가입일로 먼저 내림차순 정렬 후 그 안에서 고객이름으로 오름차순 정렬
6. COUNT(집계)
SELECT COUNT(*)
FROM 테이블 이름
WHERE 조건문
- 집계 함수 중 하나
- 행(ROW) 수 셀 때 사용
- COUNT(*) 혹은 COUNT (열이름)으로 사용
- 열이름 사용 시 NULL 제외됨
- 뒤에 AS를 붙이고 열의 새로운 이름 적기(AS 생략가능) - 10번에서 추가 설명
--as 사용
SELECT COUNT(Customer_id) as total_customers
FROM Customers
COUNT(DISTINCT 열이름) - UNIQUE 한 행의 수 집계
--DISTINCT 사용
SELECT COUNT(DISTINCT Customer_id) as total_unique_customers
FROM Customers
- MS ACCESS DB에선 오류발생
- 서브쿼리(중첩문)로 작성해야 함
SELECT COUNT(*) FROM (
SELECT DISTINCT Customer_id from Customers)
- GROUP BY와 함께 사용하여 UNIQUE별 개수 파악 가능
SELECT customer_id, COUNT(DISTINCT product_name) AS unique_products
FROM orders
GROUP BY customer_id;
7.SUM, AVG, MIN, MAX(집계)
SELECT SUM(열이름)
FROM 테이블 이름
WHERE 조건문
- 숫자 테이블만 가능(문자열은 오류 발생)
- 괄호 안에서 열이름끼리 연산 가능
- SUM: 총합계 계산
- AVG: 평균 계산(결측값 제외)
- MIN: 최솟값을 계산
- MAX: 최댓값을 계산
8. GROUP BY
SELECT 그룹핑하고 싶은 열 중 하나, SUM(계산하고 싶은열(숫자))
FROM 테이블 이름
WHERE 조건문
GROUP BY 그룹핑하고 싶은 열
- 그룹별 개수, 합계, 평균, 최솟값, 최댓값 등을 구하기 위함
- SELECT 뒤에는 열 외에는 집계 함수 (COUNT, SUM, AVG, MIN, MAX, …)를 사용해야함
- SELECT 뒤에 나오는 열과 GROUP BY 뒤에 나오는 열 동일해야 함
- WHERE 다음에 사용
- ORDER BY 전에 사용
9. HAVING
SELECT 열이름A, SUM(열이름B)
FROM 테이블 이름
WHERE 조건문
GROUP BY 열이름A
HAVING 조건문 (집계결과에 대해)
- GROUP BY 다음에 사용
- ORDER BY 전에 사용
- 조건문 사용(WHERE과 용법 비슷)
- WHERE - GROUP BY 전에 필터링
- HAVING - GROUP BY 결과를 필터링
- 보통 집계하는 열(MIN(열이름B))에 대한 조건문 사용
SELECT ORDERID, MIN(QUANTITY) FROM [ORDERDETAILS] GROUP BY ORDERID HAVING MIN(QUANTITY) >= 5
10. AS(ALIAS, 별칭)
SELECT 열이름 AS 새로운이름
FROM 테이블 이름;
--예문
SELECT 고객이름 AS 이름, 고객주소 AS 주소
FROM 고객표
- 생략 가능
- 띄어쓰기 사용 시 - "내용" 또는 [내용]
- (…) AS “MY GREAT PRODUCT”
- (…) AS [MY GREAT PRODUCT]
11. CASE WHEN(THEN, ELSE, END AS)
CASE
WHEN 조건1 THEN '이름1'
WHEN 조건2 THEN '이름2'
WHEN 조건3 THEN '이름3'
ELSE '이름4' END AS 새로운열이름
--예문
SELECT *,
CASE WHEN Sales >= 1000
THEN 'High Sale'
ELSE 'Low Sale'
END AS COLUMN_NAME
FROM 고객표
WHERE 날짜 = '2023-08-04'
- 기존의 열과 조건문을 이용하여 새로운 열을 만들고 싶을 때
- 조건문은 순차적으로 진행
- 조건끼리 겹쳐도 조건1 만족 시 바로 이름1 부여
- 마지막 ELSE 생략 가능(END는 필수)
- 생략 시 나머지는 빈 값
12. JOIN
INNER JOIN
SELECT 테이블1.열이름, 테이블2.열이름
FROM 테이블1
INNER JOIN 테이블2
ON 테이블1.열이름 = 테이블2.열이름
--예문
SELECT 고객표.고객이름, 주문내역.세일
FROM 고객표
INNER JOIN 주문내역
ON 고객표.고객번호 = 주문내역.고객번호
- 테이블 1, 테이블 2 공통으로 있는 열만 출력
- 테이블 여러 개 나오는 경우
- ⇒ AS 이용해 별칭 사용하여 코드 단축 가능
SELECT 표1.고객이름, 표2.세일
FROM 고객표 AS 표1
INNER JOIN 주문내역 AS 표2
ON 표1.고객번호 = 표2.고객번호
--고객번호와 같이 공통된 컬럼인 경우 정확히 표시
- ⇒ AS 이용해 별칭 사용하여 코드 단축 가능
- SELECT 뒤에 테이블 이름 생략 가능한 경우
- 테이블끼리 중복되는 열 이름이 없을 경우에는 생략 가능
- 중복되는 열 이름이 두 개 이상 테이블에 있을 때는 테이블 출처 표시해야 함
SELECT 고객이름, 세일 --표1.고객이름에서 표1 생략
FROM 고객표 AS 표1
INNER JOIN 주문내역 AS 표2
ON 표1.고객번호 = 표2.고객번호
- JOIN의 기본값 - INNER JOIN
- 3개 이상 테이블 JOIN - 다중 JOIN 가능
- 서브쿼리 사용하여 표현도 가능
LEFT JOIN(=LEFT OUTER JOIN)
SELECT 테이블1.열이름, 테이블2.열이름
FROM 테이블1
LEFT JOIN 테이블2
ON 테이블1.열이름 = 테이블2.열이름
--예문
SELECT 고객표.고객이름, 주문내역.세일
FROM 고객표
LEFT JOIN 주문내역
ON 고객표.고객번호 = 주문내역.고객번호
- 테이블 1에 있는 모든 행을 출력
- 테이블 1에 있고 테이블 2에 없는 값
⇒ 빈칸 - 테이블1에 있는 데이터라면 테이블 2에 “중복”된 데이터가 있는 열도 그대로 모두 출력
-
A가 구매한 책 목록 테이블 1: 고객 목록 테이블 2: 구매한 책 목록 ⇒ A가 여러 개의 책을 구매하면, 구매한 모든 책을 출력한다
- 테이블 1 - 고객 목록
고객ID 고객명 1 A 2 B
구매ID 고객ID 도서명 101 1 데이터 사이언스 입문 102 1 SQL 완전정복 103 1 머신러닝 가이드 104 2 엑셀 실무 바이블 고객ID 고객명 도서명 1 A 데이터 사이언스 입문 1 A SQL 완전정복 1 A 머신러닝 가이드 2 B 엑셀 실무 바이블
RIGHT JOIN(=RIGHT OUTER JOIN)
- 거의 쓸 일 없음(LEFT가 훨씬 직관적)
SELECT 테이블1.열이름, 테이블2.열이름
FROM 테이블1
RIGHT JOIN 테이블2
ON 테이블1.열이름 = 테이블2.열이름
FULL JOIN(=FULL OUTER JOIN)
- 테이블 1, 2에 있는 모든 행 출력(겹치지 않으면 빈칸)
- 아주 가끔 씀
- EX) 가게 주문 내역, 온라인 주문 내역이 따로 저장된 경우
SELECT 테이블1.열이름, 테이블2.열이름
FROM 테이블1
FULL JOIN 테이블2
ON 테이블1.열이름 = 테이블2.열이름
--예문
SELECT 온라인주문.고객이름, 온라인주문.세일 AS 온라인세일, 가게주문.세일 AS 가게세일
FROM 온라인주문
FULL JOIN 가게주문
ON 온라인주문.고객번호 = 가게주문.고객번호
- 모든 행 출력하므로 출력 테이블이 커짐 - 꼭 필요할 때만 사용
13. UNION
SELECT 열이름
FROM 테이블1
UNION
SELECT 열이름
FROM 테이블2
--예문
SELECT City, Country FROM Customers
WHERE Country='Germany'
UNION
SELECT City, Country FROM Suppliers
WHERE Country='Germany'
ORDER BY City;
- UNION 앞에 쓰여있는 쿼리 결과와 UNION 뒤에 써있는 쿼리 결과 합치기
- EXCEL이나 파이썬 CONCAT과 같은 역할
- 테이블의 열의 개수, 순서가 같아야 함
- 열의 이름은 달라도 됨
- 타입(boolean, date, etc)은 같아야 함
- 이름은 위의 테이블 기준으로 표시
- 중복 있을 시 - 하나만 출력
- 모두 출력 - UNION ALL
14. SubQuery
--예문
SELECT *
FROM 가게주문
WHERE 고객번호 NOT IN (SELECT 고객번호 FROM 온라인주문)
- SQL 쿼리 안에 또 다른 쿼리가 있는 것(괄호로 구별)
- SUBQUERY 이용되는 구문
- WHERE
- FROM
- SELECT
- SubQuery는 다양하게 응용이 가능, 따로 추가 글을 업로드할 예정
*본 글은 다음 영상들을 참고하여 제작하였습니다.
https://www.youtube.com/watch?v=SA6Ena4itZ4&list=PLU7aNvsXRLZckCbpF_q88k7LpWjVTX43_
https://learningspoons.com/course/detail/sql_googlesheets/
배민 사업개발팀 현업자 직강! SQL과 구글 시트로 배우는 데이터 리터러시 첫 걸음
비전공자도 바로 실무에 적용가능한 SQL, 구글 시트 강의. 내가 원하는 데이터를 SQL로 뽑아 분석하고 구글 시트로 시각화, 프로젝트를 통해 전략도출하는 데이터 리터러시 역량까지
learningspoons.com