[MySQL] 3.6 데이터 필터링 - LIKE


http://www.mysqltutorial.org 내용을 따라 익히며 정리한 글입니다. 예시에 나오는 데이터셋은 MySQL 샘플 데이터셋인 classicmodels DB입니다.


1. LIKE 소개

LIKE 연산자를 적절히 사용하는건 쿼리 성능 향상에 필수적이다. LIKE 연산자는 패턴에 기반해 데이터를 선택할 때 주로 사용된다. 따라서 WHERE 절이나 SELECT 문에서 자주 쓰인다.

LIKE 연산자는 %, _ 두 가지 특수문자와 함께 사용된다.

  • % : 0개 이상의 문자로 구성된 모든 문자열을 매치시킬 수 있다.
  • _ : 문자 하나를 매치시킬 수 있다.

2. LIKE%

SELECT
employeeNumber,
lastName,
firstName
FROM
employees
WHERE
firstName LIKE 'a%';
+----------------+----------+-----------+
| employeeNumber | lastName | firstName |
+----------------+----------+-----------+
| 1143 | Bow | Anthony |
| 1611 | Fixter | Andy |
+----------------+----------+-----------+
2 rows in set (0.00 sec)

LIKE 'a%'를 사용해 이름이 A로 시작하는 사람들을 추려냈다.
비슷한 방법으로 LIKE '%on' 을 사용해 성이 ‘-on’ 으로 끝나는 사람들을 찾아보자.

SELECT
employeeNumber,
lastName,
firstName
FROM
employees
WHERE
lastName LIKE '%on';
+----------------+-----------+-----------+
| employeeNumber | lastName | firstName |
+----------------+-----------+-----------+
| 1056 | Patterson | Mary |
| 1088 | Patterson | William |
| 1166 | Thompson | Leslie |
| 1216 | Patterson | Steve |
+----------------+-----------+-----------+
4 rows in set (0.00 sec)

%on 앞뒤로 붙이면 on 이 들어가는 성을 모두 찾을 수 있다.

SELECT
employeeNumber,
lastName,
firstName
FROM
employees
WHERE
lastname LIKE '%on%';
+----------------+-----------+-----------+
| employeeNumber | lastName | firstName |
+----------------+-----------+-----------+
| 1056 | Patterson | Mary |
| 1088 | Patterson | William |
| 1102 | Bondur | Gerard |
| 1166 | Thompson | Leslie |
| 1216 | Patterson | Steve |
| 1337 | Bondur | Loui |
| 1504 | Jones | Barry |
+----------------+-----------+-----------+
7 rows in set (0.00 sec)

3. LIKE 와 언더스코어(_)

Tom, Tim 첨 T로 시작하고 m으로 끝나는 세 글자 이름을 가진 사람을 찾으려면 _ 를 사용할 수 있다.

SELECT
employeeNumber,
lastName,
firstName
FROM
employees
WHERE
firstname LIKE 'T_m';
+----------------+----------+-----------+
| employeeNumber | lastName | firstName |
+----------------+----------+-----------+
| 1619 | King | Tom |
+----------------+----------+-----------+
1 row in set (0.00 sec)

4. LIKENOT

성이 B로 시작하지 않는 사람들을 추릴때 NOT LIKE 'B%' 를 사용한다. 대소문자 여부는 상관이 없다.

SELECT
employeeNumber,
lastName,
firstName
FROM
employees
WHERE
lastName NOT LIKE 'B%';
----------------+-----------+-----------+
| employeeNumber | lastName | firstName |
+----------------+-----------+-----------+
| 1002 | Murphy | Diane |
| 1056 | Patterson | Mary |
| 1076 | Firrelli | Jeff |
| 1088 | Patterson | William |
| 1165 | Jennings | Leslie |
| 1166 | Thompson | Leslie |
| 1188 | Firrelli | Julie |
| 1216 | Patterson | Steve |
| 1286 | Tseng | Foon Yue |
| 1323 | Vanauf | George |
| 1370 | Hernandez | Gerard |
| 1401 | Castillo | Pamela |
| 1504 | Jones | Barry |
| 1611 | Fixter | Andy |
| 1612 | Marsh | Peter |
| 1619 | King | Tom |
| 1621 | Nishi | Mami |
| 1625 | Kato | Yoshimi |
| 1702 | Gerard | Martin |
+----------------+-----------+-----------+
19 rows in set (0.00 sec)

5. LIKEESCAPE

매치시키려는 패턴이 10%_20과 같이 와일드카드 문자를 포함하고 있을 경우 ESCAPE 를 사용해 와일드카드 문자를 일반 문자로 해석하도록 처리할 수 있다. 이스케이프 문자를 명시하지 않으면 \ 백슬래시 문자가 디폴트로 적용된다. 이스케이프 문자는 와일드카드 문자 바로 앞에 넣는다.

SELECT
productCode,
productName
FROM
products
WHERE
productCode LIKE '%\_20%';

$ 와 같은 문자를 이스케이프 문자로 지정할 수도 있다.

SELECT
productCode,
productName
FROM
products
WHERE
productCode LIKE '%$_20%' ESCAPE '$';

LIKE 연산자는 MySQL이 전체 테이블을 스캔하여 일치하는 행을 찾도록 한다. 이는 데이터베이스 엔진이 인덱스를 사용해 빠른 검색을 하지 못하는 결과를 초래한다. 결과적으로 행 수가 많은 테이블에서 데이터를 쿼리할 때 LIKE 연산자를 사용하면 쿼리의 성능이 떨어진다.

[MySQL] 3.5 데이터 필터링 - BETWEEN


http://www.mysqltutorial.org 내용을 따라 익히며 정리한 글입니다. 예시에 나오는 데이터셋은 MySQL 샘플 데이터셋인 classicmodels DB입니다.


1. 연산자 BETWEEN 소개

BETWEEN 을 사용하면 범위를 지정해 데이터를 불러올 수 있다.
SELECT, UPDATE, DELETE 문의 WHERE 절에서 사용하는 경우가 많다.

expr [NOT] BETWEEN begin_expr AND end_expr;

위 구문에서 expr, begin_expr, end_expr 에는 모두 동일한 유형의 데이터가 들어간다.

expr의 값이 begin_expr 의 값보다 크거나 같고 (>=) end_expr 의 값보다 작거나 같으면(<=) true 를 반환하고 그렇지 않으면 0을 반환한다.

NOT BETWEENexpr의 값이 begin_expr의 값보다 작거나(<) end_expr의 값보다 큰 경우(>) true를 반환하고 그렇지 않으면 0을 반환한다.

표현식이 NULL이면 BETWEENNULL 값을 반환한다.

2. BETWEEN 예시

2-1

products 테이블에서 구매가가 90~100인 상품의 상품코드, 상품명, 구매가를 불러온다.

SELECT
productCode,
productName,
buyPrice
FROM
products
WHERE
buyPrice BETWEEN 90 AND 100;
+-------------+--------------------------------------+----------+
| productCode | productName | buyPrice |
+-------------+--------------------------------------+----------+
| S10_1949 | 1952 Alpine Renault 1300 | 98.58 |
| S10_4698 | 2003 Harley-Davidson Eagle Drag Bike | 91.02 |
| S12_1099 | 1968 Ford Mustang | 95.34 |
| S12_1108 | 2001 Ferrari Enzo | 95.59 |
| S18_1984 | 1995 Honda Civic | 93.89 |
| S18_4027 | 1970 Triumph Spitfire | 91.92 |
| S24_3856 | 1956 Porsche 356A Coupe | 98.30 |
+-------------+--------------------------------------+----------+
7 rows in set (0.00 sec)

BETWEEN 대신 기호를 사용해도 결과는 위와 같다.

SELECT
productCode,
productName,
buyPrice
FROM
products
WHERE
buyPrice >= 90 AND buyPrice <= 100;

2-2

products 테이블에서 구매가가 20~100 범위에 있지 않은 상품의 상품코드, 상품명, 구매가를 불러온다.

SELECT
productCode,
productName,
buyPrice
FROM
products
WHERE
buyPrice NOT BETWEEN 20 AND 100;
+-------------+-------------------------------------+----------+
| productcode | productname | buyprice |
+-------------+-------------------------------------+----------+
| S10_4962 | 1962 LanciaA Delta 16V | 103.42 |
| S18_2238 | 1998 Chrysler Plymouth Prowler | 101.51 |
| S24_2840 | 1958 Chevy Corvette Limited Edition | 15.91 |
| S24_2972 | 1982 Lamborghini Diablo | 16.24 |
+-------------+-------------------------------------+----------+
4 rows in set (0.00 sec)

이 역시 BETWEEN 대신 기호와 논리 연산자를 사용해 같은 결과를 가져올 수 있다.

SELECT
productCode,
productName,
buyPrice
FROM
products
WHERE
buyPrice < 20 OR buyPrice > 100;

3. BETWEEN 사용해 날짜 데이터 추리기

BETWEEN 연산자를 날짜 값에 정확하게 적용하기 위해선 CAST 함수를 쓰는게 좋다. CAST 함수는 값을 BINARY, CHAR, DATE, DATETIME, TIME 등의 타입으로 바꿔주는 함수를 말한다.

예를 들어, 배송 마감일(requireddate)이 2003년 1월 1일부터 1월 31일까지인 주문들을 가져오기 위해선 다음과 같이 쿼리문을 작성한다.

SELECT
orderNumber,
requiredDate,
status
FROM
orders
WHERE
requireddate BETWEEN
CAST('2003-01-01' AS DATE) AND
CAST('2003-01-31' AS DATE);
+-------------+--------------+---------+
| orderNumber | requiredDate | status |
+-------------+--------------+---------+
| 10100 | 2003-01-13 | Shipped |
| 10101 | 2003-01-18 | Shipped |
| 10102 | 2003-01-18 | Shipped |
+-------------+--------------+---------+
3 rows in set (0.00 sec)

[MySQL] 3.4 데이터 필터링 - IN


http://www.mysqltutorial.org 내용을 따라 익히며 정리한 글입니다. 예시에 나오는 데이터셋은 MySQL 샘플 데이터셋인 classicmodels DB입니다.


1. 연산자 IN 소개

IN 연산자를 사용하면 WHERE 절의 조건을 덕지덕지 붙일 필요 없이 값들의 집합이나 서브쿼리에서 반환된 값들 중 지정된 값과 일치하는 데이터를 보다 간편하게 불러올 수 있다. 예시를 보자.

2. IN 예시

2-1.

offices 테이블에서 미국과 프랑스 내 사무실들의 오피스코드, 도시, 전화번호, 국가를 반환하는 쿼리문을 작성하라.(IN을 사용하지 않고 작성)

SELECT
officeCode,
city,
phone
FROM
offices
WHERE
country = 'USA' OR country = 'France';

+------------+---------------+-----------------+---------+
| officecode | city | phone | country |
+------------+---------------+-----------------+---------+
| 1 | San Francisco | +1 650 219 4782 | USA |
| 2 | Boston | +1 215 837 0825 | USA |
| 3 | NYC | +1 212 555 3000 | USA |
| 4 | Paris | +33 14 723 4404 | France |
+------------+---------------+-----------------+---------+
4 rows in set (0.00 sec)

2-2.

offices 테이블에서 미국과 프랑스 내 사무실들의 오피스코드, 도시, 전화번호, 국가를 반환하는 쿼리문을 작성하라.(IN을 사용해 작성)

SELECT
officeCode,
city,
phone,
country
FROM
offices
WHERE
country IN ('USA' , 'France');
+------------+---------------+-----------------+---------+
| officecode | city | phone | country |
+------------+---------------+-----------------+---------+
| 1 | San Francisco | +1 650 219 4782 | USA |
| 2 | Boston | +1 215 837 0825 | USA |
| 3 | NYC | +1 212 555 3000 | USA |
| 4 | Paris | +33 14 723 4404 | France |
+------------+---------------+-----------------+---------+
4 rows in set (0.00 sec)

2-3.

offices 테이블에서 미국과 프랑스가 아닌 다른 나라 사무실들의 오피스코드, 도시, 전화번호, 국가를 반환하는 쿼리문을 작성하라.(IN을 사용해 작성)

SELECT
officeCode,
city,
phone,
country
FROM
offices
WHERE
country NOT IN ('USA' , 'France');
+------------+--------+------------------+-----------+
| officeCode | city | phone | country |
+------------+--------+------------------+-----------+
| 5 | Tokyo | +81 33 224 5000 | Japan |
| 6 | Sydney | +61 2 9264 2451 | Australia |
| 7 | London | +44 20 7877 2041 | UK |
+------------+--------+------------------+-----------+
3 rows in set (0.00 sec)

3. 서브쿼리와 IN

IN 연산자는 서브쿼리와 함께 사용되곤 한다.
하나 이상의 테이블에서 값 목록을 가져와 IN 연산자의 입력 값으로 서브쿼리를 사용합니다.

3-1.

ordersorderDetails 테이블에서 주문액 60000 이상인 주문의 주문번호, 고객번호, 상태, 선적일을 가져오는 쿼리를 작성하라.

이 문제는 다음처럼 두 단계로 풀 수 있다.

  1. 먼저 GROUP BYHAVING 을 사용해 주문액이 60000 이상인 주문번호를 반환하는 쿼리를 작성한다.
SELECT
orderNumber
FROM
orderdetails
GROUP BY
orderNumber
HAVING
SUM(quantityOrdered * priceEach) > 60000;
+-------------+
| orderNumber |
+-------------+
| 10165 |
| 10287 |
| 10310 |
+-------------+
3 rows in set (0.01 sec)
  1. 위에서 알아낸 주문번호를 IN 연산자에 입력해 orders 테이블에서 필요한 데이터를 가져온다.
SELECT
orderNumber,
customerNumber,
status,
shippedDate
FROM
orders
WHERE
orderNumber IN (10165,10287,10310);
+-------------+----------------+---------+-------------+
| orderNumber | customerNumber | status | shippedDate |
+-------------+----------------+---------+-------------+
| 10165 | 148 | Shipped | 2003-12-26 |
| 10287 | 298 | Shipped | 2004-09-01 |
| 10310 | 259 | Shipped | 2004-10-18 |
+-------------+----------------+---------+-------------+
3 rows in set (0.00 sec)

3-2.

위 풀이에서의 두 쿼리를 합치면 아래와 같이 쓸 수 있다.

SELECT
orderNumber,
customerNumber,
status,
shippedDate
FROM
orders
WHERE
orderNumber IN (SELECT orderNumber
FROM orderdetails
GROUP BY orderNumber
HAVING SUM(quantityOrdered * priceEach) > 60000);
+-------------+----------------+---------+-------------+
| orderNumber | customerNumber | status | shippedDate |
+-------------+----------------+---------+-------------+
| 10165 | 148 | Shipped | 2003-12-26 |
| 10287 | 298 | Shipped | 2004-09-01 |
| 10310 | 259 | Shipped | 2004-10-18 |
+-------------+----------------+---------+-------------+
3 rows in set (0.00 sec)

[MySQL] 3.3 데이터 필터링 - OR


http://www.mysqltutorial.org 내용을 따라 익히며 정리한 글입니다. 예시에 나오는 데이터셋은 MySQL 샘플 데이터셋인 classicmodels DB입니다.


1. 연산자 OR 소개

논리 연산자 OR 는 두 개의 불리언 값을 받아 하나라도 True 이면 True 를 리턴한다.

2. OR short-circuit evaluation

SELECT 1 = 1 OR 1 / 0 ;
+------------+
| 1=1 or 1/0 |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)

위 예에서 1 = 1TRUE 를 리턴한다. Short Circuit Evaluation에 따라 1 / 0 연산은 하지 않는다. 만약 연산을 했다면 division by zero 에러가 떴을 것이다.

3. 연산자 우선순위

연산자 우선 순위(Operator precedence)란 두 개 이상의 논리 연산자를 사용할 경우 어떤 논리 연산자를 먼저 평가할지 판단하는 기준을 말한다. 우선 순위가 더 높은 연산자를 먼저 평가하게 되는데, 예를 들어 ANDOR가 함께 있다면 AND 를 먼저 보고 그 뒤에 OR 를 평가한다.

3.1

SELECT true OR false AND false;
+-------------------------+
| true or false and false |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
  1. false AND false 를 먼저 평가한다. false 를 리턴.
  2. 다음으로 true OR false 를 평가한다. true 를 리턴.

3.2

SELECT (true OR false) AND false;
  1. 괄호가 쳐진 true OR false 를 먼저 평가한다. true 를 리턴.
  2. 다음으로 true AND false 를 평가한다. false 를 리턴.

4. OR 예시

4.1

USA와 France에 있는 고객들의 이름, 국가를 뽑아내고 싶을 경우 다음과 같이 쿼리를 작성한다.

SELECT
customername, country
FROM
customers
WHERE
country = 'USA' OR country = 'France'
LIMIT 10;
+------------------------------+---------+
| customername | country |
+------------------------------+---------+
| Atelier graphique | France |
| Signal Gift Stores | USA |
| La Rochelle Gifts | France |
| Mini Gifts Distributors Ltd. | USA |
| Mini Wheels Co. | USA |
| Land of Toys Inc. | USA |
| Saveley & Henriot, Co. | France |
| Muscle Machine Inc | USA |
| Diecast Classics Inc. | USA |
| Technics Stores Inc. | USA |
+------------------------------+---------+
10 rows in set (0.00 sec)

4.2

USA와 France에 있는 고객들 중 신용한도가 10만 이상인 고객들의 이름, 국가를 뽑아내고 싶을 경우 다음과 같이 쿼리를 작성한다. AND 가 먼저 계산되지 않도록 OR 를 괄호로 묶어줘야 함에 주의한다.

SELECT
customername, country, creditLimit
FROM
customers
WHERE
(country = 'USA' OR country = 'France')
AND creditlimit > 100000
LIMIT 8;
+------------------------------+---------+-------------+
| customername | country | creditLimit |
+------------------------------+---------+-------------+
| La Rochelle Gifts | France | 118200.00 |
| Mini Gifts Distributors Ltd. | USA | 210500.00 |
| Land of Toys Inc. | USA | 114900.00 |
| Saveley & Henriot, Co. | France | 123900.00 |
| Muscle Machine Inc | USA | 138500.00 |
| Diecast Classics Inc. | USA | 100600.00 |
| Collectable Mini Designs Co. | USA | 105000.00 |
| Marta's Replicas Co. | USA | 123700.00 |
+------------------------------+---------+-------------+
8 rows in set (0.00 sec)

4.3

위 4.2의 예에서 OR 를 괄호로 묶어주지 않으면 AND 가 먼저 계산되면서 아래와 같이 미국 고객에 신용 한도 조건이 붙지 않은 결과가 발생한다.

SELECT
customername, country, creditLimit
FROM
customers
WHERE
country = 'USA' OR country = 'France' AND creditlimit > 100000
LIMIT 8;
+------------------------------+---------+-------------+
| customername | country | creditLimit |
+------------------------------+---------+-------------+
| Signal Gift Stores | USA | 71800.00 |
| La Rochelle Gifts | France | 118200.00 |
| Mini Gifts Distributors Ltd. | USA | 210500.00 |
| Mini Wheels Co. | USA | 64600.00 |
| Land of Toys Inc. | USA | 114900.00 |
| Saveley & Henriot, Co. | France | 123900.00 |
| Muscle Machine Inc | USA | 138500.00 |
| Diecast Classics Inc. | USA | 100600.00 |
+------------------------------+---------+-------------+
8 rows in set (0.00 sec)

[MySQL] 3.2 데이터 필터링 - AND


http://www.mysqltutorial.org 내용을 따라 익히며 정리한 글입니다. 예시에 나오는 데이터셋은 MySQL 샘플 데이터셋인 classicmodels DB입니다.


1. 연산자 AND 소개

논리 연산자 ANDSELECT, UPDATE, DELETE 문의 WHERE 절에서 자주 사용된다.

두 개 이상의 불리언 값을 받아 모두 True 이면 True 를 리턴한다.

TRUE FALSE NULL
TRUE TRUE FALSE NULL
FALSE FALSE FALSE FALSE
NULL NULL FALSE NULL

MySQL은 AND 연산자가 있는 표현식을 평가하면서 결과가 확실하게 예측되고 나면 나머지 연산을 하지 않는다. (Short Circuit Evaluation) AND 앞에서 False가 나오면 AND 뒤에 나오는 연산은 생략한다는 의미다.

SELECT 1 = 0 AND 1 / 0 ;
+-------------+
| 1=0 and 1/0 |
+-------------+
| 0 |
+-------------+
1 row in set (0.00 sec)

MySQL에서 0FALSE로, 0 이 아닌 값들은 TRUE 로 다뤄진다.
위 예에서 1 = 0FALSE 를 리턴한다. Short Circuit Evaluation에 따라 1 / 0 연산은 하지도 않았다. 만약 연산을 했다면 division by zero 에러가 떴을 것이다.

2. AND 예시

2-1.

AND 연산자를 사용해 미국 캘리포니아 주에 사는 고객들을 추리시오.

SELECT
customername,
country,
state
FROM
customers
WHERE
country = 'USA' AND state = 'CA';
+------------------------------+---------+-------+
| customername | country | state |
+------------------------------+---------+-------+
| Mini Gifts Distributors Ltd. | USA | CA |
| Mini Wheels Co. | USA | CA |
| Technics Stores Inc. | USA | CA |
| Toys4GrownUps.com | USA | CA |
| Boards & Toys Co. | USA | CA |
| Collectable Mini Designs Co. | USA | CA |
| Corporate Gift Ideas Co. | USA | CA |
| Men 'R' US Retailers, Ltd. | USA | CA |
| The Sharp Gifts Warehouse | USA | CA |
| West Coast Collectables Co. | USA | CA |
| Signal Collectibles Ltd. | USA | CA |
+------------------------------+---------+-------+
11 rows in set (0.00 sec)

2-2.

AND 연산자를 사용하면 두 개 이상의 불리언 표현식을 조합할 수 있다. 미국 캘리포니아 주에 살면서, 신용한도가 100K 이상인 고객들을 추리시오.

SELECT   customername,
country,
state,
creditlimit
FROM customers
WHERE country = 'USA'
AND state = 'CA'
AND creditlimit > 100000;
+------------------------------+---------+-------+-------------+
| customername | country | state | creditlimit |
+------------------------------+---------+-------+-------------+
| Mini Gifts Distributors Ltd. | USA | CA | 210500.00 |
| Collectable Mini Designs Co. | USA | CA | 105000.00 |
| Corporate Gift Ideas Co. | USA | CA | 105000.00 |
+------------------------------+---------+-------+-------------+
3 rows in set (0.00 sec)
© 2019 THE DATASCIENTIST All Rights Reserved.
Theme by hiero