저도 처음 데이터 분석과 프로그래밍을 배울 때, 까만 터미널 화면과 수많은 열이 빽빽하게 찬 데이터베이스 테이블을 보고 머릿속이 새하얘졌던 기억이 생생해요. 수천만 줄이나 되는 거대한 엑셀 시트 같은 데이터베이스를 도대체 어떻게 다뤄야 할지 정말 막막했거든요. 그런데 막상 실무를 겪어보니 복잡한 문법을 다 외울 필요는 전혀 없더라고요. 😊
데이터베이스 관리의 핵심 언어인 SQL(Structured Query Language)은 사실 ‘데이터 창고지기에게 원하는 데이터를 정중하게 요청하는 대화법’에 불과해요. 그리고 그 대화의 뼈대를 이루는 문법이 바로 데이터를 조회하는 SELECT, 원하는 조건만 쏙 골라내는 WHERE, 흩어진 퍼즐 조각을 맞추는 JOIN이랍니다. 오늘 이 세 가지 개념만 확실하게 잡아두셔도 웬만한 실무 데이터 추출은 자신 있게 해내실 수 있을 거예요!
1. 데이터 창고에서 원하는 물건 꺼내기: SELECT 문 🤔
SQL 쿼리문을 작성할 때 가장 먼저 마주치고, 가장 빈번하게 쓰는 키워드가 바로 SELECT예요. 일상어로 번역하면 “내가 말한 이 컬럼(열)들을 가져와서 화면에 보여줘!”라는 뜻이랍니다. 항상 어디서 데이터를 꺼내올지 지정하는 FROM 절과 한 쌍으로 움직여요.
기본 구조는 너무나도 직관적이에요. 예를 들어 회원 정보를 담고 있는 users라는 테이블에서 회원의 이름과 이메일 주소만 확인하고 싶다면 아래처럼 작성하면 돼요.
📝 기본 SELECT 문법 예시
SELECT name, email FROM users;
→ 해석: users 테이블(창고)로 가서 name(이름)과 email(이메일) 컬럼만 쏙 뽑아서 출력해줘!
만약 테이블의 모든 컬럼을 한꺼번에 보고 싶다면 별표 기호인 아스테리스크(*)를 사용해 SELECT * FROM users; 형태로 쓸 수 있어요. 하지만 실무에서는 데이터 용량이 수십 기가바이트에 달하는 경우가 많아서 무턱대고 *를 쓰면 데이터베이스 서버가 비명을 지르게 되니 꼭 필요한 열만 지정하는 습관을 들이는 것이 좋습니다.
우리가 쿼리를 쓸 때는 SELECT를 먼저 쓰고 그 뒤에 FROM을 적지만, 데이터베이스 엔진은 내부적으로 FROM 절을 먼저 읽어 대상 테이블을 확정한 뒤에야 비로소 SELECT에 적힌 열들을 골라냅니다. 이 순서를 머릿속에 기억해 두시면 앞으로 배울 복잡한 서브쿼리나 JOIN 문을 이해할 때 훨씬 수월해져요!
2. 필요한 데이터만 정교하게 걸러내는 필터: WHERE 절 📊
데이터베이스에 수백만 명의 회원 정보가 들어있는데, 매번 전체 회원을 불러와서 눈으로 찾을 수는 없겠죠? 이때 검색 조건을 걸어 내가 원하는 조건에 딱 맞는 행(Row)만 걸러내는 마법의 필터가 바로 WHERE 절입니다.
WHERE 절은 엑셀의 데이터 필터 기능과 똑같아요. 비교 연산자(=, >, <)와 논리 연산자(AND, OR, NOT), 그리고 SQL만의 유용한 특수 연산자들을 다양하게 조합할 수 있습니다.
WHERE 절에서 자주 쓰이는 핵심 연산자 총정리
| 연산자 구분 | 문법 예시 | 기능 설명 | 실무 팁 |
|---|---|---|---|
| 비교 연산 | age >= 25 | 특정 기준값과의 대소 비교 및 일치 여부 확인 | 문자열은 작은따옴표(‘ ‘)로 감싸야 함 |
| IN 연산자 | city IN (‘서울’, ‘부산’) | 나열된 여러 목록 중 하나라도 일치하면 추출 | OR 조건을 여러 번 쓰는 것보다 가독성이 뛰어남 |
| BETWEEN | score BETWEEN 80 AND 100 | 지정한 두 값 사이(경계값 포함)의 범위 검색 | 날짜 범위 조회 시 시간 값(00:00:00) 포함 여부 주의 |
| LIKE 연산자 | email LIKE ‘%@naver.com’ | 와일드카드(%)를 활용한 부분 문자열 일치 검색 | 앞에 %가 붙으면 인덱스를 타지 못해 느려질 수 있음 |
데이터베이스에서 비어있는 값은 ‘0’이나 빈 문자열(”)이 아니라 데이터 자체가 없음을 뜻하는 NULL 상태입니다. 이때
WHERE address = NULL처럼 등호(=)를 쓰면 SQL 엔진은 무조건 거짓(False)으로 판단하여 아무 결과도 반환하지 않아요. 반드시 IS NULL 또는 IS NOT NULL 연산자를 사용해야 합니다!
3. 흩어진 퍼즐을 하나로 엮는 기술: JOIN 문 🧮
관계형 데이터베이스(RDBMS)에서는 데이터의 중복을 막고 무결성을 지키기 위해 여러 개의 테이블로 데이터를 쪼개어 보관해요. 예를 들어 ‘고객 테이블’에는 고객의 개인정보만 두고, ‘주문 테이블’에는 주문 내역만 담아두는 식이죠. 그렇다면 “어떤 고객이 어떤 상품을 얼마에 주문했는가?”를 한 화면에서 보고 싶다면 어떻게 해야 할까요? 바로 JOIN 문을 통해 두 테이블을 공통된 연결 고리로 합쳐야 합니다.
📝 JOIN 기본 연결 공식
SELECT A.열, B.열 FROM 테이블A AS A [JOIN 종류] JOIN 테이블B AS B ON A.공통키 = B.공통키
JOIN의 세계에서 가장 대표적인 두 주인공은 INNER JOIN과 LEFT JOIN이에요. 작동 원리를 차근차근 살펴보면 전혀 어렵지 않습니다.
1) INNER JOIN (교집합): 양쪽 테이블 모두에 매칭되는 데이터가 존재하는 경우에만 합쳐서 출력해요. 한 번도 주문하지 않은 회원은 주문 테이블에 없으므로 결과에서 제외됩니다.
2) LEFT OUTER JOIN (기준 테이블 전체): 왼쪽(FROM 뒤에 오는) 테이블의 모든 데이터를 무조건 살려두고, 오른쪽 테이블에 매칭되는 정보가 있으면 붙이고 없으면 NULL로 채워 넣어요. 신규 가입자나 주문 이력이 없는 고객까지 전부 확인하고 싶을 때 유용합니다.
→ 결론: 실무 조회 업무의 80% 이상은 이 INNER JOIN과 LEFT JOIN 두 가지로 해결됩니다! 😊
🔢 실시간 SQL 쿼리 빌더 체험 도구
4. 실무 쿼리 작성 시 놓치기 쉬운 핵심 포인트 👩💻👨💻
문법의 형태를 아는 것과 실무에서 오류 없이 깔끔한 쿼리를 작성하는 것에는 약간의 간극이 있어요. 제가 주니어 시절 가장 많이 실수했던 부분들을 공유해 드릴게요. 쿼리의 실제 실행 순서를 머릿속에 도식화해두면 문법 오류를 사전에 99% 방지할 수 있습니다.
- FROM & JOIN: 탐색 대상이 될 데이터 테이블을 메모리에 올리고 연결 고리를 엮습니다.
- WHERE: 가져온 거대한 데이터 세트에서 불필요한 행들을 가차 없이 버립니다.
- GROUP BY & HAVING: 필요하다면 특정 기준으로 묶고 그룹 조건으로 필터링합니다.
- SELECT: 필터링을 거치고 최종적으로 살아남은 행에서 지정한 컬럼들만 화면에 출력합니다.
- ORDER BY & LIMIT: 출력할 결과물의 정렬 순서를 잡고 개수를 제한합니다.
여러 테이블을 JOIN할 때는
FROM customers AS c JOIN orders AS o처럼 테이블 이름 뒤에 AS 별칭을 붙여 간결하게 축약해 주세요. 그 후 c.name, o.amount처럼 컬럼명 앞에 출처를 명시해 주면 다른 사람이 쿼리를 읽을 때도 가독성이 극대화되고, 같은 이름의 컬럼이 존재할 때 발생하는 ‘모호한 열 이름(Ambiguous Column)’ 에러를 깔끔하게 예방할 수 있답니다.
5. 실전 예시: 쇼핑몰 VIP 고객 주문 내역 분석 📚
이론을 익혔으니 이제 실전 비즈니스 상황에 적용해 볼까요? 마케팅 팀장님이 여러분에게 다가와 “서울에 거주하는 VIP 고객님들이 최근 5만 원 이상 결제한 주문 내역과 연락처를 뽑아주실 수 있나요?”라고 요청한 상황을 가정해 볼게요.
비즈니스 분석 시나리오
- 고객 테이블 (customers): customer_id(고객번호), name(이름), phone(전화번호), city(거주도시), grade(회원등급)
- 주문 테이블 (orders): order_id(주문번호), customer_id(주문고객번호), amount(결제금액), order_date(주문일시)
3단계 쿼리 조립 과정
1) FROM & JOIN: 두 테이블을 customer_id로 묶어 고객 정보와 주문 정보를 한 판에 올립니다.
2) WHERE: 거주도시가 ‘서울’이고, 등급이 ‘VIP’이며, 결제금액이 ‘50,000원 이상’인 조건만 추려냅니다.
3) SELECT: 마케팅팀에 전달할 핵심 항목인 고객명, 연락처, 주문번호, 결제금액을 최종 지정합니다.
최종 완성 쿼리문
SELECT
c.name AS 고객명,
c.phone AS 연락처,
o.order_id AS 주문번호,
o.amount AS 결제금액
FROM customers AS c
INNER JOIN orders AS o
ON c.customer_id = o.customer_id
WHERE c.city = '서울'
AND c.grade = 'VIP'
AND o.amount >= 50000
ORDER BY o.amount DESC;
이 쿼리 하나로 복잡하게 분리되어 있던 데이터가 단 몇 초 만에 마케팅팀에서 즉시 활용할 수 있는 깔끔한 리스트로 탈바꿈했어요. SELECT, WHERE, JOIN의 기본기만 충실히 다져두면 어떤 실무 요구사항도 이처럼 단계별로 쉽게 해결할 수 있답니다. 정말 매력적이지 않나요? 😊
마무리: 핵심 내용 요약 📝
지금까지 관계형 데이터베이스를 다루는 가장 기초적이면서도 강력한 세 가지 문법을 살펴보았어요. SQL은 무작정 코드를 외우기보다 데이터가 어떻게 저장되어 있고 어떤 흐름으로 거름망을 거쳐 화면에 뿌려지는지 그 구조적인 흐름을 이해하는 것이 훨씬 중요해요.
오늘 배운 SELECT, WHERE, JOIN의 3대 핵심 규칙을 아래 요약 카드로 한눈에 정리해 두었으니 잊어버릴 때마다 꺼내보시면서 직접 손으로 쿼리를 작성해 보시길 추천해 드려요. 배움에 있어 직접 에러를 마주하고 고쳐보는 것만큼 빠른 지름길은 없으니까요!
SQL 핵심 문법 치트시트
자주 묻는 질문 ❓
LOWER() 함수나 UPPER() 함수로 변환 후 비교하는 것이 안전합니다.
SQL의 기초 문법을 공부하시면서 더 궁금한 점이나 실무에서 마주친 알쏭달쏭한 쿼리 오류가 있다면 언제든지 댓글로 편하게 질문 남겨주세요~ 함께 고민하고 해결해 봐요! 😊