안녕하세요. SQLER의 코난 김대우입니다.
이번 강좌에서는, 2-5. WHERE절의 조건에 의한 행의 검색을 진행 하겠습니다.
SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록
이번시간에는 SQL Server에서 데이터를 필터링하는 WHERE절 강좌를 진행합니다.
TL;DR
WHERE 절을 이용해 데이터를 필터링할 수 있습니다. 각 데이터형에 맞는 필터링 조건 처리 방법과 비교 연산자, NULL 처리를 예제 SQL 구문으로 확인합니다.
데이터 필터링
Production.Product 테이블이 있습니다. 우리 회사의 제품 목록이 기록된 테이블입니다. 오후 5시, 퇴근 시간이 되어 가는데 갑자기 팀장님의 긴급 요청이 들어옵니다.
"대우님! 우리 AdventureWorks 회사에서 판매하는 제품들 중 제품 가격(ListPrice)이 10 이상인 제품 목록이 급하게 필요합니다. 오늘 중으로 목록을 제출해 주세요!”
데이터베이스 공부를 시작한 지 얼마 되지도 않았는데 큰일입니다. 이때, SELECT 구문의 WHERE이라는 조건절로 데이터 필터링이 가능한 것을 알게 되었습니다.
WHERE 절에 조건을 추가해 결과를 필터링
간략히 구조만 살펴보겠습니다. 다양한 예제로 필터링할 테니 아래 내용은 참고정도만 하셔도 좋습니다. 여러 예제를 실행하시고 다시 아래 설명을 살펴보시면 도움 되실 거에요.
SELECT select_list FROM table_list WHERE search_conditions |
주의사항
- WHERE 절에는 가능하면 NOT은 사용하지 않는 것이 좋다.
- NOT을 사용하면 색인의 도움을 받을 수 없다.
- 연산자 앞에는 가능하면 컬럼 이름이 오도록 한다.
탐색 조건에 포함할 수 있는 것들
비교 연산자 |
=, >, <, >=, <=, <>, !=, !, !> |
범위 |
BETWEEN, NOT BETWEEN |
리스트 |
IN, NOT IN |
일치하는 문자열 |
LIKE, NOT LIKE |
알 수 없는 값 |
IS NULL, IS NOT NULL |
결합 |
AND, OR |
부정 |
NOT |
그렇다면, Production.Product 테이블에서 ListPrice가 10 이상인 항목을 필터링해보겠습니다.
SELECT * FROM Production.Product WHERE ListPrice >= 10;
다른 예제입니다.
제품 주문을 기록하는 Sales.SalesOrderHeader 테이블에서 팬매금액(SubTotal)이 10,000보다 큰 항목을 조회해 볼까요?
SELECT * FROM Sales.SalesOrderHeader WHERE SubTotal > 10000;
Production.Product 테이블에서 제품명(Name)이 Bearing Ball인 제품을 골라내 보겠습니다.
SELECT * FROM Production.Product WHERE Name = 'Bearing Ball';
숫자 데이터 비교와는 다른 게 보입니다. 이렇게 문자열의 비교는 반드시 ' ' 로 작은따옴표(single quotation)를 사용합니다. 그 이유는 123이라는 수치형 데이터와 '123'라는 문자열형 데이터를 식별하기 위해서입니다. 문자열을 비교할 때는 “=” 연산자 보다 더 좋은 “LIKE” 연산자가 있습니다. 아래에서 예제로 살펴보겠습니다.
다음은 Production.Product 테이블에서 Color가 NULL인 항목을 필터링합니다.
SELECT * FROM Production.Product WHERE Color is NULL;
SQL의 NULL에 대해서
자! 처음으로 NULL이 등장합니다. NULL에 대해서 살펴보겠습니다. 많은 분들이 NULL이란 “빈 문자열”으로 오해하는 경우가 종종 있습니다. 아닙니다. NULL은 “값이 지정되지 않았다”라는 의미입니다. ' ' (빈 문자열)은 빈 문자열이 값으로 지정되어 있다는 의미이며 NULL은? 어떤 값도 지정되지 않았다는 의미입니다. Python pandas에 익숙하시면 NaN과 비슷합니다.
☑️ 챗GPT 활용: Python pandas의 NaN에 대해서 알려줘
여러 조건 처리
다음은 Production.Product 테이블에서 ListPrice가 9.5보다 크고 13.99보다 작은 제품만 조회합니다. 두 개 이상의 조건으로 필터링을 할 경우 “AND’를 이용해 추가합니다.
SELECT * FROM Production.Product WHERE ListPrice > 9.5 AND ListPrice < 13.99;
유사한 방식의 between이라는 범위 검색이 있습니다.
SELECT * FROM Production.Product WHERE ListPrice BETWEEN 9.5 AND 13.99;
방식과 결과도 비슷하지만 바로 위의 AND 검색과 결과가 엄밀하게는 다릅니다. 바로 9.5 “이상’ 13.99 “이하”로 비교 값이 다릅니다. 위의 between 구문과 같으려면 아래와 같이 이상, 이하가 되어야 합니다.
SELECT * FROM Production.Product WHERE ListPrice >= 9.5 AND ListPrice <= 13.99;
다음은 Production.Product 테이블에서 Color가 Black 또는 Silver인 항목만 필터링해 보겠습니다. 일반적으로 이렇게 OR 연산자를 이용합니다.
SELECT * FROM Production.Product WHERE Color = 'Black' OR Color = 'Silver';
위의 OR 방식이 아니라 IN을 사용하는 방법도 있습니다. 여러 건을 나열할 경우 IN 연산자가 유용하겠지요?
SELECT * FROM Production.Product WHERE Color IN ('Black', 'Silver');
아울러, 이후 배우시겠지만 하위 쿼리(Sub query)를 이용할 때에도 IN 연산자가 유용합니다.
그렇다면, Black 또는 Silver가 아닌 색깔만 필터링하려면 어떻게 할까요?
위의 예제와 다르게 NOT을 사용하는 방식입니다. (NOT은 WHERE 절에서 최대한 사용하지 않는 게 좋습니다.
이후 색인, INDEX 강좌에서 상세하게 논의합니다.)
SELECT * FROM Production.Product WHERE Color NOT IN ('Black', 'Silver');
LIKE 비교 연산자
위의 예제에서 문자열을 비교할 때 WHERE Name = 'Bearing Ball' 이렇게 사용했습니다. 그냥 = 연산자를 사용해 비교했습니다. 이 방법보다 다양한 문자열 조건 처리를 위해 LIKE 연산자 사용을 권장합니다.
SELECT select_list FROM table_list WHERE expression [NOT] LIKE “string” |
LIKE 연산자에서 정규 표현식(regular expression) 패턴의 와일드카드를 사용 가능합니다.
와일드카드(Wildcard)
% : 임의의 0개 이상의 문자열
_ : 임의의 한 글자
[ ] : 지정된 범위 또는 집합 안의 한 문자
[^] : 지정된 범위 또는 집합에 없는 한 문자
☑️ 챗GPT 활용: 정규 표현식과 와일드카드(Wildcard)에 대해서 알려줘
예제를 수행합니다.
Production.Product 테이블에서 제품명(Name)이 앞 글자가 뭘로 시작하건 상관없고 끝글자가 뭘로 끝나건 상관없이 문자열에 ‘Road’라는 문자열이 존재하는 데이터만 필터링할 때 LIKE 구문을 어떻게 사용할까요?
SELECT * FROM Production.Product WHERE Name LIKE '%Road%';
Production.Product 테이블에서 제품명(Name)이 처음은 ‘HL’로 시작하고 뒤는 아무 문자열이 나와도 상관없는 예제를 실행합니다.
SELECT * FROM Production.Product WHERE Name LIKE 'HL%';
이번엔 한 글자를 치환할 수 있는 ‘_‘(언더바라고 부르지요)를 사용합니다. 첫 글자는 ‘H’로 시작하고 다음 한 글자는 모르며 다음에 ‘x’ 이어서 뒤의 문자열은 아무거나 상관없는 구문을 실행합니다.
SELECT * FROM Production.Product WHERE Name LIKE 'H_x%';
다음으로 첫 글자는 ‘C’로 시작하며 다음에 ‘h’ 자가 없고 아울러 뒷글자가 아무거나 상관없는 문자열을 필터링하는 예제입니다.
SELECT * FROM Production.Product WHERE Name LIKE 'C[^h]%';
정리
문자열을 비교할 때는 LIKE를 사용하세요. 숫자형 데이터 비교에는 =, !=, <, >을 이용해 비교합니다.
끝으로 아래 내용은 약간 더 복잡한 쿼리입니다. 실행해 보시고 왜 이렇게 나오는지 생각해 보세요.
SELECT * FROM Production.Product WHERE (ListPrice >= 9.5 AND ListPrice <= 13.99) OR Name LIKE '%Socks%';
SELECT Name, Color, ListPrice FROM Production.Product WHERE Name LIKE 'Mountain%' OR Color LIKE 'White' AND ListPrice > 3.99;
WHERE 조건은 개발 업무를 하면서 쿼리를 작성할 때 항상 사용됩니다. 차근차근 예제 코드들을 살펴보시고 내 것으로 만들어 두길 바랍니다.
SQL 강좌 책 구매
강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다.