SQL 기초 배우기
SQL 기초 가이드
안녕하세요, SQL을 처음 접하시는 분들을 위해 자주 사용하는 문법과 개념을 정리해보았습니다.
1. SQL 실행 순서
SQL 쿼리는 일반적으로 WITH, SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT 순으로 작성되지만, 실제 실행 순서와는 차이가 있습니다.
1
FROM > WHERE > GROUP BY > HAVING > SELECT > DISTINCT > ORDER BY > LIMIT
실행 순서는 위와 같으며, 위 구문들을 하나씩 파헤쳐보도록 하겠습니다.
2. 데이터 불러오기
SELECT 및 FROM은 데이터를 불러오는 역할을 합니다. SELECT은 테이블의 열을 Select 하는 것이고, FROM은 데이터를 가져올 테이블 또는 데이터셋의 출처를 의미합니다.
1
2
SELECT *
FROM data;
SELECT *은 FROM 에서 불러온 data 테이블의 모든 열(column)을 가져온다는 것을 의미합니다. 별표(*)는 전체 컬럼을 불러옵니다.
특정 컬럼만 선택하고 싶을 경우, 아래처럼 쿼리를 작성하면 됩니다.
1
2
SELECT name, age
FROM data;
Note: 쿼리문의 마지막에 있는 ; 세미콜론은 해당 쿼리의 마무리를 의미합니다. 쓰지 않는 경우, 다음 쿼리문에 영향을 줄 수 있으니 주의해야 합니다.
3. 조건문
기본 WHERE 문
WHERE 절은 조건에 따라 행을 필터링하는데 사용됩니다. 조건을 만족하는 데이터만 반환됩니다.
1
2
3
SELECT *
FROM table
WHERE score > 80;
위 쿼리는 점수가 80 보다 큰 행만 선택합니다.
논리 연산자
AND, OR, IN, NOT, BETWEEN A AND B 같은 논리 연산자는 여러 조건을 결합할 때 사용됩니다.
AND&BETWEEN A AND B
1
WHERE gender = 'M' AND age BETWEEN 20 AND 30;
위 쿼리는 성별이 Male이고 나이가 20세 이상 30세 이하인 행만 반환합니다.
IN
1
WHERE city IN ('Seoul', 'Busan');
도시가 Seoul 또는 Busan인 행만 필터링합니다.
NOT IN
1
WHERE name NOT IN ('John', 'Jane');
이름이 John과 Jane이 아닌 사람들만 반환합니다. NOT IN을 통해 특정 값을 제외한 행만 선택할 수 있습니다.
OR
1
WHERE job = 'teacher' OR job = 'engineer';
직업이 teacher 이거나 engineer인 행만 반환합니다.
NULL 값 확인
IS NULL 또는 IS NOT NULL을 사용해 값이 없는 데이터를 필터링할 수 있습니다.
1
WHERE email IS NULL;
위 쿼리는 email 컬럼의 NULL인 행만 선택합니다.
Note: Null은 0이나 빈 문자열과 같은 의미가 아닙니다. 값 자체가 존재하지 않는 상태를 의미합니다.
4. 데이터 정렬
행 정렬하기
ORDER BY 절은 결과를 하나 이상의 컬럼을 기준으로 정렬합니다. 기본값은 오름차순(ASC)이며, 내림차순(DESC)으로 설정할 수 있습니다.
1
ORDER BY score DESC;
위 쿼리는 score 컬럼을 높은 점수부터 내림차순으로 정렬합니다.
결과 수 제한하기
LIMIT 절은 결과로 반환되는 행의 수를 제한합니다. 데이터가 많을 때 일부만 미리 확인할 수 있어 유용합니다.
1
LIMIT 10;
위 쿼리는 상위 10개의 행만 반환합니다. pandas dataframe 에서 .head() 처럼 쓰입니다.
5. 데이터 그룹화
집계 함수
집계 함수는 여러 행을 요약하여 하나의 값을 계산할 때 사용됩니다. 대표적인 함수는 다음과 같습니다:
SUM(): 총합AVG(): 평균값COUNT(): 행의 개수MIN()/MAX(): 최소값 / 최대값
1
2
3
SELECT department, AVG(salary)
FROM employees
GROUP BY department;
이 쿼리는 employees 테이블에서 department별로 그룹을 나눈 뒤, 각 부서의 AVG(salary)를 계산합니다.
HAVING 절 (그룹 조건부 필터링)
HAVING 절은 집계 이후의 결과를 필터링할 때 사용됩니다. WHERE 절은 집계 전에 동작하기 때문에 집계 함수를 사용할 수 없기 때문에, 집계 이후 조건문을 쓰려면 HAVING을 사용해야 합니다.
1
2
3
4
5
SELECT category, SUM(sales) AS total_sales
FROM orders
GROUP BY category
HAVING total_sales > 100000;
-- WHERE SUM(sales) > 100000 : 오류 발생 --
이 쿼리는 category별로 총 매출(SUM(sales))을 구한 뒤, 매출이 100,000을 초과하는 항목만 필터링합니다.
6. 서브 쿼리
서브쿼리는 하나의 쿼리 내부에 포함된 또 다른 쿼리를 의미합니다. 필요한 데이터가 다른 테이블의 조건을 기반으로 할 때 자주 사용되며, 주로 WHERE 절 또는 FROM 절에 사용됩니다.
WHERE 절에서의 서브쿼리
1
2
3
4
5
6
7
SELECT *
FROM users
WHERE id IN (
SELECT user_id
FROM purchases
WHERE amount > 10000
);
이 쿼리는 purchases 테이블에서 10,000원을 초과해 구매한 user_id를 먼저 찾은 후, 해당 ID를 가진 사용자만 users 테이블에서 조회합니다.
Note: 서브쿼리는 괄호 () 안에 작성됩니다.
FROM 절에서의 서브쿼리 (aka 인라인 뷰)
서브쿼리를 FROM 절에 사용하면 임시 테이블처럼 다룰 수 있습니다. 인라인 뷰 (Inline View) 라고도 부르며, 복잡한 데이터를 미리 가공한 후 그 결과에 다시 쿼리를 적용할 수 있습니다.
1
2
3
4
5
6
SELECT region, AVG(temp)
FROM (
SELECT region, temp
FROM weather
WHERE month = 'July'
) AS sub;
이 쿼리는 먼저 weather 테이블에서 7월의 region과 temp만 추출한 뒤, 해당 결과를 sub라는 이름의 임시 테이블로 간주하여 지역별 평균 기온(AVG(temp))을 계산합니다.
7. 테이블 조인 (JOIN)
조인(JOIN)은 두 개 이상의 테이블을 공통된 컬럼을 기준으로 결합할 때 사용됩니다.
하나의 테이블에 모든 정보가 없을 때, 관련된 테이블을 합쳐서 완전한 데이터를 만들 수 있습니다.
INNER JOIN
INNER JOIN은 양쪽 테이블에서 조건에 일치하는 행만 결과로 반환합니다.
1
2
3
4
SELECT A.name, B.score
FROM students AS A
JOIN scores AS B
ON A.id = B.student_id;
이 쿼리는 students 테이블과 scores 테이블을 학생 ID를 기준으로 연결하여 (ON A.id = B.student_id) 각 학생의 이름과 점수를 함께 출력합니다.
LEFT JOIN 및 RIGHT JOIN
LEFT JOIN은 왼쪽 테이블의 모든 행을 유지하면서,
오른쪽 테이블에서 조건에 일치하는 행이 있을 경우 그 값을 함께 가져옵니다.
오른쪽에 일치하는 값이 없으면 NULL로 표시됩니다. (RIGHT JOIN은 그 반대입니다)
1
2
3
4
SELECT A.name, B.score
FROM students AS A
LEFT JOIN scores AS B
ON A.id = B.student_id;
이 쿼리는 students 테이블의 모든 학생 이름을 출력합니다. score 값이 있는 학생은 점수도 함께 표시되며, 점수가 없는 학생은 score 컬럼에 NULL이 표시됩니다.
8. 윈도우 함수 (Window Functions)
윈도우 함수는 현재 행을 기준으로 그룹 내 다른 행들과 연관된 계산을 수행할 수 있게 해줍니다.
결과를 집계하지 않고도 누적 합계, 순위, 이전/다음 값 참조 등을 할 수 있어 유용합니다.
RANK, ROW_NUMBER
아래 함수들은 지정한 정렬 기준에 따라 각 행에 순위 또는 인덱스를 부여합니다.
1
2
3
4
SELECT name, score,
RANK() OVER (ORDER BY score DESC) AS rank,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;
RANK()는 동점이면 동일한 순위를 부여하고, 다음 순위는 건너뜁니다.
예를 들어 점수가 동일한 두 학생이 1등이면, 그 다음 순위는 2등이 아니라 3등이 됩니다.1, 1, 3, 4, …
ROW_NUMBER()는 무조건 순차적으로 고유한 인덱스를 부여합니다.
동점 여부와 상관없이 1부터 차례대로 증가합니다.1, 2, 3, 4, …
LAG, LEAD
이 함수들은 현재 행 기준으로 이전 또는 다음 행의 값을 가져옵니다.
1
2
3
4
SELECT user_id, timestamp,
LAG(timestamp, 1) OVER (PARTITION BY user_id ORDER BY timestamp) AS prev_time,
LEAD(timestamp, 1) OVER (PARTITION BY user_id ORDER BY timestamp) AS next_time
FROM logs;
위 쿼리는 사용자별 로그 기록에서 LAG(직전 시간) 및 LEAD(직후 시간)을 함께 보여줍니다.
해당 값이 없을 경우 NULL이 반환됩니다.
9. 자료형 변환: CAST
CAST() 함수는 값을 다른 자료형으로 변환할 때 사용됩니다. 예를 들어, 문자열을 숫자로 변환해 계산할 수 있도록 합니다.
1
2
SELECT CAST(price AS INT) AS p_int
FROM sales;
이 예시는 price가 문자형(str)일 때, 정수형(int)으로 변환하여 계산 가능하도록 합니다.
10. 그 외 문법
패턴 찾기: LIKE
LIKE 연산자는 문자열에서 특정 패턴이 포함된 값을 필터링할 때 사용됩니다.
%: 0개 이상의 문자_: 정확히 1개의 문자
1
2
WHERE name LIKE 'Kim%'; -- 'Kim'으로 시작하는 이름
WHERE comment LIKE '%error%'; -- 'error'를 포함하는 댓글
별칭 사용: AS
AS를 통해 컬럼 또는 테이블에 임시 이름(별칭) 을 붙여 가독성을 높일 수 있습니다.
1
2
SELECT name AS n
FROM users;
name 컬럼이 n 으로 표시됩니다.
쿼리 합치기 (UNION)
UNION은 두 개의 SELECT 결과를 위아래로 합칠 때 사용됩니다. 중복되는 행은 자동으로 제거되며, 중복을 허용하려면 UNION ALL을 사용합니다.
1
2
3
SELECT * FROM Table1 AS t1
UNION
SELECT * FROM Table2 AS t2;
t1 과 t2 테이블이 합쳐지며, 쿼리가 작동하려면 두 테이블의 컬럼 개수, 순서 등이 일치해야 합니다.
마치며
이상으로 SQL 입문자용 기초 가이드를 마칩니다.
pandasql 및 Bigquery 사용법이 궁금하시면 아래 링크를 참고해주세요! How to Use SQL with pandasql and BigQuery?
감사합니다.