Special WHERE operators - 특별한 WHERE 연산자
당신은 이미 복잡한 SQL 쿼리들과 논리 표현식을 작성 할 줄 압니다.
이번 주제에서는, 우리는 특별한 WHERE
연산자들을 더 보게 될 겁니다.
BETWEEN
,IN
,LIKE
,EXISTS
,ANY
,IS NULL
andIS DISTINCT FROM
위의 단어들은 당신의 쿼리들을 더 발전되고 가독성 있게 만듭니다.
BETWEEN operator - BETWEEN 연산자
WHERE
절 내부의 BETWEEN
연산자는 주어진 영역의 값들을 선택합니다.
주어진 영역은 최소와 최대 값의 집합인데, 이는 날짜, 숫자, 텍스트 데이터를 담을 수 있습니다.
BETWEEN
연산자는 포괄적인데, 이는 최소값과 최대값들이 영역 내부에 포함되게 합니다.
함께 제품들을 선택해 보는데, 가격이 8
과 같거나 크고, 13
보다 작거나 같은 것을 고릅니다.
한 번 주어진 products
테이블에서 골라보죠!
product | price |
---|---|
milk | 10 |
tofu | 15 |
pasta | 12 |
bread | 8 |
WHERE BETWEEN
을 사용한 쿼리는 밑의 예제와 같습니다 :
SELECT
product
FROM
products
WHERE
price BETWEEN 8 AND 13;
위의 쿼리의 결과 집합은 세 개의 줄을 가집니다.
product |
---|
milk |
pasta |
bread |
BETWEEN
을 제외한 쿼리도 같은 결과 집합을 얻을 수 있습니다.
SELECT
product
FROM
products
WHERE
(price >= 8
AND price <= 13);
위의 쿼리를 본다면, WHERE BETWEEN
연산자가
WHERE
절에서의 >= AND <=
표현에 대한 단축어라는 것을 생각할 수 있습니다.
바깥 영역의 모든 제품을 선택하기 위해 NOT BETWEEN
연산자를 사용 할 수 있습니다.
SELECT
product
FROM
products
WHERE
price NOT BETWEEN 8 AND 13;
결과 집합은 원래 나왔던 세 개의 줄을 제외하고 있습니다. :
product |
---|
tofu |
IN operator - IN 연산자
WHERE
절에서의 IN
연산자는 다중 OR 조건절의 단축어이기도 하며, 여러 개의 값을 표기하기 허용합니다.
이전 예제의 products
테이블로부터 10
, 12
, 16
가격과 같은 제품들을 선택 해 봅시다.
SELECT
product
FROM
products
WHERE
price IN (10, 12, 16);
이 쿼리의 결과는 밑과 같습니다. :
product |
---|
milk |
pasta |
10
, 12
, 16
과 다른 가격의 제품들을 선택하기 위해서
NOT
을 사용하여 IN
연산자를 부정 할 수 있습니다.
SELECT
product
FROM
products
WHERE
price NOT IN (10, 12, 16);
이 쿼리를 사용하면, milk
, pasta
를 제외한 모든 제품을 가져옵니다.
product |
---|
tofu |
bread |
LIKE operator - Like 연산자
LIKE
연산자는 WHERE
절에서 쓰일 수 있는데, 문자열이 패턴과 맞는지 확인하기 위해서 쓰입니다.
패턴을 만들기 위해 두 개의 wildcard match options 를 사용할 수 있습니다. : %
and _
.
%
는 모든 숫자, 혹은 문자를 표현합니다. : 0, 1, ...
예를 들어, 패턴을 %s%
로 쓴다면,
문자열 s
, toaster
, string
, cats
문자열이 이 패턴과 일치합니다.
_
는 정확히 하나의 문자를 표현합니다.
따라서, 패턴을 s_
로 작성한다면, 문자열 so
가 이 패텬과 일치합니다.
문자열 s
, soap
는 일치하지 않습니다.
함께 products
테이블로부터 'a' 문자열이 들어간 모든 제품들을 선택해 보겠습니다.
SELECT
product
FROM
products
WHERE
product LIKE '%a%';
쿼리는 이러한 테이블을 반환합니다 :
product |
---|
pasta |
bread |
BETWEEN
과 IN
연산자처럼,
a
문자열이 들어가지 않은 제품 이름을 얻기 위해 NOT
과 LIKE
연산자로 부정할 수 있습니다.
SELECT
product
FROM
products
WHERE
product NOT LIKE '%a%';
EXISTS operator
EXISTS
연산자는 서브쿼리가 어떠한 레코드라도 반환하는지 아닌지 체크합니다.
만약 서브쿼리가 어떠한 레코드라도 반환한다면, EXISTS
연산자는 TRUE
를 반환합니다.
그 반대라면,(어떠한 레코드도 반환되지 않음) FALSE
를 반환합니다.
suppliers
테이블을 봅시다. :
supplier | product |
---|---|
Good food | pasta |
Happy farm | milk |
Good food | milk |
Happy farm | bread |
Good food | cheese |
우리는 EXISTS
연산자를 사용하여 milk
와 pasta
둘 다 공급하는 공급자들을 모두 선택합니다. :
SELECT DISTINCT
supplier
FROM suppliers AS milk_suppliers
WHERE
product = 'milk'
AND EXISTS
(SELECT supplier
FROM
suppliers
WHERE
product = 'pasta'
AND supplier = milk_suppliers.suppliers
);
이 경우, 쿼리의 결과는 밑과 같습니다 :
supplier |
---|
Good food |
부정 EXISTS
연산자는 서브쿼리가 어떠한 레코드라도 반환한다면 FALSE
를 반환합니다.
그 반대의 경우 (어떤 레코드도 반환하지 않은 상황) , TRUE
를 반환합니다.
우리는 이전 쿼리를 수정하여 milk
는 공급하지만, pasta
는 공급하지 않는 공급자를 선택 할 수 있습니다.
SELECT DISTINCT
supplier
FROM
suppliers AS milk_suppliers
WHERE
product = 'milk'
AND NOT EXISTS
(SELECT
supplier
FROM
suppliers
WHERE
product = 'pasta'
AND suppliers = milk_suppliers
);
이 쿼리는 이 테이블을 반환합니다 :
milk_suppliers |
---|
Happy farm |
products :
product | price |
---|---|
milk | 10 |
tofu | 15 |
pasta | 12 |
bread | 8 |
suppliers :
supplier | product |
---|---|
Good food | pasta |
Happy farm | milk |
Good food | milk |
Happy farm | bread |
Good food | cheese |
ANY operator - ANY 연산자
ANY
연산자는 서브쿼리가 어떠한 조건이라도 충족한다면, TRUE
를 반환합니다.
products
, suppliers
테이블을 사용하고,
ANY
연산자를 사용하여 products
테이블 내부 목록에 없는 제품을 공급하는 공급자를 찾습니다.
supplier 중에서,
products
테이블에 없는 제품을 파는 사람을 찾는다! 라는 의미이다.
SELECT DISTINCT
supplier
FROM
suppliers
WHERE
NOT product = ANY (SELECT product FROM products);
쿼리의 결과는 밑과 같습니다 :
supplier |
---|
Good food |
ANY
연산자는 표준 비교 연산자 이후에만 사용 할 수 있습니다.
ex - =
, !=
, <=
, 등등...
supplier
과product
가 같은 줄에 존재한다.
product 값을products
테이블의 product 값과 비교한다.ANY
를 통해 선택된 product 값이 반환되는데,product
: suppliers =product
: products
와 같은 형태가 된다.
이 때,NOT
이 존재하기 때문에,suppliers.product.
!=products.product.all()
과 같은
형태가 된다. - 이는 실존하는 코드가 아니라, 이해를 위한 코드.
따라서,NOT
으로 인해products
목록에 존재하지 않는 제품을 파는suppliers
를 찾는다.
나도 헷갈려서 짚고 넘어가기
1. EXISTS
서브쿼리로 작성된 코드가 하나라도 레코드를 내뱉는다면, TRUE
로 환산된다.
그 외의 경우, FALSE
로 환산된다.
반환값 : boolean
2. ANY
서브쿼리로 작성된 코드가 모든 products 값을 반환한다.
이 때, supplier에서 선택된 제품과 모든 products 값을 비교합니다.
Hyperskill 문서에서는 TRUE
, FALSE
로 치환된다고 설명하는데,
실제로는 비교식을 위해 값이 반환된다고 생각하면 됩니다.
suppliers.product
와 products.All()
을 비교한다고 해석하면 됩니다.
IS NULL operator - IS NULL 연산자
IS NULL
연산자는 컬럼의 값이 NULL
과 일치한다면 TRUE
를 반환합니다.
밑의 persons
테이블을 보겠습니다. :
name | city |
---|---|
John Oh | New-York |
Eve Comer | NULL |
Kim Wilson | London |
persons
테이블로부터 도시에 대한 정보가 없는 모든 줄을 선택하기 위해 IS NULL
연산자를 사용 할 수 있습니다.
SELECT
name
FROM
persons
WHERE
city IS NULL;
쿼리 결과는 밑과 같습니다. :
name |
---|
Eve Comer |
도시에 대한 정보가 NULL 이 아닌 모든 줄을 선택하기 위해 IS NOT NULL
연산자를 사용 할 수 있습니다.
SELECT
name
FROM
persons
WHERE
city IS NOT NULL;
IS DISTINCT FROM operator - IS DISTINCT FROM 연산자
평범한 비교 연산자들은 TRUE
혹은 FALSE
를 반환하는데, 이것이 아니면 NULL
을 반환합니다.
이 결과를 원하지 않을 때, IS DISTINCT FROM
연산자가 쓰입니다.
IS DISTINCT FROM
연산자는 !=
, <>
와 매우 유사합니다.
이 연산자는 두 값이 서로 다르다면 TRUE
를 반환하며, 그 반대의 경우 FALSE
를 반환합니다.
만약 양 측의 값이 NULL
이라면, IS DISTINCT FROM
연산자는 TRUE
를 반환합니다.
이 연산자는 표준 비균등 체킹 연산자와 구별되는 점 입니다.
비균등 체킹 연산자 -
!=
,<>
...
다른 의미로, 이 구성은 본질적으로 NULL
을 일반 값처럼 작업하며,
UNKNOWN
대신 TRUE
또는 FALSE
를 반환합니다.
NULL = NULL => UNKNOWN
NULL IS NOT DISTINCT FROM NULL => TRUE
persons
테이블로부터 New-York 도시 값과 같지 않는 모든 줄을 선택합니다.
SELECT
*
FROM
persons
WHERE
city IS DISTINCT FROM 'New-York';
위의 쿼리는 두 개의 줄을 선택합니다. :
name | city |
---|---|
Eve Comer | NULL |
Kim Wilson | London |
이 연산자를 부정하는 IS NOT DISTINCT FROM
연산자는 null을 다루지 않는 균등 체킹 연산자처럼 작동합니다.
그리고 양 쪽 값이 모두 NULL
이라면, TRUE
를 반환합니다.
양 쪽 값을 비교할 때, 마치 객체 비교처럼 작동하는 것으로 이해했다.
persons
테이블에서 도시 값이 NULL
과 같은 모든 줄을 선택합니다.
SELECT
*
FROM
persons
WHERE
city IS NOT DISTINCT FROM NULL;
이 쿼리는 이 줄을 반환합니다.
name | city |
---|---|
Eve Comer | NULL |
Conclusion - 결론
특별한 연산자인 WHERE
은 쿼리들을 더 간단하고, 더 발전된 서브쿼리를 만들 수 있게 해 줍니다.
연습합시다!
'Hyperskill - 컴퓨터 CS 및 영어 독해 > Introducing to SQL' 카테고리의 다른 글
Basic DELETE statement - 기초적인 DELETE 문법 (0) | 2024.04.16 |
---|---|
Basic INSERT statement - 기초적인 INSERT 문법 (0) | 2024.04.15 |
The NULL value - null 값 (0) | 2024.04.13 |
Logic and comparison expressions - 로직, 비교 표현식 (1) | 2024.04.12 |
SELECT FROM statement - SELECT FROM 구문 (0) | 2024.04.10 |