2023. 1. 30. 21:34
MySQL의 SELECT기능 다뤄보기
이 게시글은 전반적으로 SELECT기능을 기술한 것이 대부분이다.
이 게시글에 모든 예시는 아래 링크를 통해서 사용해 볼 수 있다.스키마 이름이나 칼럼이름 역시 같아 결과값이 그대로 적용되어 보여진다.
https://www.w3schools.com/mysql/trymysql.asp?filename=trysql_select_all
데이터 Customers에서 모든내용 보기
SELECT * FROM Customers;
-- 이와 같이 주석을 달 수 있다.
원하는 column(열)만 골라서 보기
SELECT CustomerName FROM Customers;
--Customers스키마에서 CustomerName의 열만 골라서 보여준다.
SELECT CustomerName, ContactName, Country
FROM Customers;
--이렇게 다중으로 볼 수도 있다.
테이블의 column이 아닌 값 보기
SELECT
CustomerName, 1, 'Hello', NULL
FROM Customers;
-- 1과 Hello와 NULL은 테이블의 column이 아니다.
-- 하지만 위와같이 입력하면 해당 내용과 같은 것들만 보여진다.
원하는 row(행)만 선택해서 보기
SELECT * FROM Orders
WHERE EmployeeID = 3;
-- 데이터 Orders에서 모든것 중에서 WHERE(조건문)을
-- 사용해서 EmployeeID가 3인 행만 보여지게 된다.
SELECT * FROM OrderDetails
WHERE Quantity < 5;
-- 이런식으로 조건문을 꼭 등호가 아니여도 된다.
-- if문처럼 TRUE or FALSE로 반환되도록 잘 붙여주면 된다.
원하는 데이터 순서대로 가져오기
ORDER BY 구문을 사용하여 특정 column을 기준으로 잡고
-- 오름, 내림차순으로 볼 수 있다. Default는 오름차순이다.
-- ASC = 오름차순 / DESC = 내림차순
SELECT * FROM Customers
ORDER BY ContactName;
-- 아무것도 지정해주지 않았기 때문에 ContactName을 기준으로
-- 오름차순으로 정렬된다.
SELECT * FROM OrderDetails
ORDER BY ProductID ASC, Quantity DESC;
-- 이런 경우 먼저 나온 column이 먼저 기준이 되어 정렬되고
-- 먼저 정렬된 것을 기준으로 그 다음 column이 정렬된다.
원하는 만큼만 데이터 가져오기
-- LIMIT {가져올 갯수} 또는 LIMIT {건너뛸 갯수}, {가져올 갯수} 를 사용하여,
-- 원하는 위치에서 원하는 만큼만 데이터를 가져올 수 있다.
SELECT * FROM Customers
LIMIT 10;
-- (첫줄부터 10까지)
SELECT * FROM Customers
LIMIT 0, 10;
-- (0~10까지)
SELECT * FROM Customers
LIMIT 30, 10;
-- (30번째줄부터 시작해서 10줄까지)
원하는 별명(alias)으로 데이터 가져오기
SELECT
CustomerId AS ID,
CustomerName AS NAME,
Address AS ADDR
FROM Customers;
SELECT
CustomerId AS '아이디',
CustomerName AS '고객명',
Address AS '주소'
FROM Customers;
사칙연산
1. 기본 사칙연산
- +, -, *, /
각각 더하기, 빼기, 곱하기, 나누기 - %, MOD
나머지
SELECT 1 + 2;
SELECT 5 - 2.5 AS DIFFERENCE;
SELECT 3 * (2 + 4) / 2, 'Hello';
SELECT 10 % 3;
- 문자열에 사칙연산을 가하면 0으로 인식한다.
SELECT 'ABC' + 3;
SELECT 'ABC' * 3;
SELECT '1' + '002' * 3;
-- 숫자로 구성된 문자열은 숫자로 자동인식
- 또 다른 예제
SELECT
OrderID + ProductID
FROM OrderDetails;
-- OrderID의 숫자와 ProductID의숫자가 더해진다.
SELECT
ProductName,
Price / 2 AS HalfPrice
FROM Products;
-- ProductName과 Price를 나누기 2한 결과값의
-- 데이터이름을 HalfPrice로 보여지게 했다.
2. 참/거짓 관련 연산자
- MySQL에서는 TRUE는 1, FALSE는 0으로 저장됩니다.
SELECT TRUE, FALSE;
-- true = 1 , false = 0
- 또 다른 예제
SELECT !TRUE, NOT 1, !FALSE, NOT FALSE;
-- !true = 0, not 1 = 0, !false = 1, not false = 1
-- 트루의 반대는 펄스라서 0, not은 아니다의 뜻
SELECT 0 = TRUE, 1 = TRUE, 0 = FALSE, 1 = FALSE;
-- 0, 1, 1, 0
-- 1=true이고 0=false이기 때문이다.
SELECT * FROM Customers WHERE City = 'Berlin';
-- 전체 데이터에서 where조건문에 의해서 시티가 베를린인 것을 select한다.
- IS = 양쪽이 모두 TRUE 또는 FALSE
IS NOT = 한쪽은 TRUE, 한쪽은 FALSE
SELECT TRUE IS TRUE;
-- true는 true가 맞다. return 1;
SELECT TRUE IS NOT FALSE;
-- true는 false가 아니다. return 1;
SELECT (TRUE IS FALSE) IS NOT TRUE;
-- true는 false이다. <= 이것은 true가 아니다. return 1;
- AND, && = 양쪽이 모두 TRUE일 때만 TRUE
OR, || = 한쪽은 TRUE면 TRUE
Javascript와 동일하게 작동한다.
SELECT TRUE AND FALSE, TRUE OR FALSE;
-- Javascript ver.
-- true && false = false, true || false = true
SELECT 2 + 3 = 6 OR 2 * 3 = 6;
-- 5와 6이지만 or을 사용했기때문에 true를 반환.
SELECT * FROM Orders
WHERE
CustomerId = 15 AND EmployeeId = 4;
-- and를 썼기 때문에 두 조건 모두 충족하는 데이터만 보임.
-- CustomerId = 15 OR EmployeeId = 4; 이면 두 조건중 하나만
-- 충족해도 보여지게 된다.
SELECT * FROM Products
WHERE
ProductName = 'Tofu' OR CategoryId = 8;
-- 두 조건중 하나라도 충족한 경우 모두 보여진다.
SELECT * FROM OrderDetails
WHERE
ProductId = 20
AND (OrderId = 10514 OR Quantity = 50);
-- ProductId = 20이면서 OrderId = 10514이거나
-- Quantity = 50인 데이터를 모두 보여준다.
- = 양쪽 값이 같음
!=, <> 양쪽 값이 다름
>, < (왼쪽, 오른쪽) 값이 더 큼
>=, <= (왼쪽, 오른쪽) 값이 같거나 더 큼
SELECT 1 = 1, !(1 <> 1), NOT (1 < 2), 1 > 0 IS NOT FALSE;
-- 1, 1, 0, 1
SELECT 'A' = 'A', 'A' != 'B', 'A' < 'B', 'A' > 'B';
-- 1, 1, 1, 0
-- 알파뱃은 나중에 나오는 알파뱃일수록 크다고 판정된다.
-- MySQL의 기본 사칙연산자는 대소문자 구분을 하지 않는다.
SELECT 'A' = 'a';
-- true이다. 구분하지 않기때문에
SELECT
ProductName, Price,
Price > 20 AS EXPENSIVE
FROM Products;
-- ProductName과 Price데이터를 보여주고
-- Price가 20보다 높으면 EXPENSIVE라는 별명에
-- 1이 추가된다 (20보다 높으면 참이 되기 때문)
SELECT
ProductName, Price,
NOT Price > 20 AS CHEAP
FROM Products;
-- ProductName과 Price데이터를 보여주고
-- Price가 20보다 크지 않은 것(not)은 CHEAP이라는 별명에
-- 1이 추가 된다.
- BETWEEN {MIN} AND {MAX} = 두 값 사이에 있다.
NOT BETWEEN {MIN} AND {MAX} = 두 값 사이가 아닌 곳에 있다.
SELECT 5 BETWEEN 1 AND 10;
-- 5는 1과 10 사이에 있다. = true
SELECT 'banana' NOT BETWEEN 'Apple' AND 'camera';
-- a와 c사이에 b가 있는건 맞지만 not이 붙어서 false를 반환한다.
SELECT * FROM OrderDetails
WHERE ProductID BETWEEN 1 AND 4;
-- OrderDetails에서 ProductID가 1~4인 데이터만 보여진다.
SELECT * FROM Customers
WHERE CustomerName BETWEEN 'b' AND 'c';
-- b와 c사이는 b로 시작하는 모든 문장을 말한다.
-- c를 넘기진 말아야 하니 c로시작하는 문장은 제외된다.
- IN (...) 괄호 안의 값들 가운데 있다.
NOT IN (...) 괄호 안의 값들 가운데 없다.
SELECT 1 + 2 IN (2, 3, 4)
-- 1+2 = 3 괄호안에 3 있으니까 true를 반환한다.
SELECT 'Hello' IN (1, TRUE, 'hello')
-- hello가 있으니 true를 반환. 대소문자를 구분안한다는 것을 기억하자.
SELECT * FROM Customers
WHERE City IN ('Torino', 'Paris', 'Portland', 'Madrid')
-- Customers데이터에서 City내부에
-- 'Torino', 'Paris', 'Portland', 'Madrid'가 있는 데이터만 보여진다.
- LIKE '... % ...' 0~N개 문자를 가진 패턴
LIKE '... _ ...' _ 갯수만큼의 문자를 가진 패턴
SELECT
'HELLO' LIKE 'hel%', = 1
-- hel이후 어떤 문자가 와도 true
'HELLO' LIKE 'H%', = 1
-- h로 시작하고 그 이후 어떤 문자가 있던 true
'HELLO' LIKE 'H%O', = 1
-- H로 시작해서 O로 끝나기만 하면 true
'HELLO' LIKE '%O', = 1
-- 앞에 몇글자가 있든 무슨 글자가 있든 O로 끝나면 true
'HELLO' LIKE '%HELLO%', = 1
-- HELLO라는 글자 앞과 뒤에 어떤 문자가 얼마나 있든
-- HELLO만 있다면 true, 0~N개라서 아무것도 없이 HELLO여도 true
'HELLO' LIKE '%H', = 0
-- H로 끝나야 true인데 HELLO이기때문에 O로 끝나서 false를 반환한다.
'HELLO' LIKE 'L%' = 0
-- L로 시작해야 하는데 HELLO라서 false를 반환한다.
연산자 총정리!
SELECT
'HELLO' LIKE 'HEL__', = 1
'HELLO' LIKE 'h___O', = 1
'HELLO' LIKE 'HE_LO', = 1
'HELLO' LIKE '_____', = 1
'HELLO' LIKE '_HELLO', = 0
'HELLO' LIKE 'HEL_', = 0
'HELLO' LIKE 'H_O' = 0
-- 무슨 글자든 _ 의 갯수에 맞춰서 트루와 펄스를 반환한다.
/*
[ +, -, *, / ] === 각각 더하기, 빼기, 곱하기, 나누기
[ %, MOD ] === 나머지
[ IS ] === 양쪽이 모두 TRUE 또는 FALSE
[ IS NOT] === 한쪽은 TRUE, 한쪽은 FALSE
[ AND, && ] === 양쪽이 모두 TRUE일 때만 TRUE
[ OR, || ]=== 한쪽은 TRUE면 TRUE
[ = ] === 양쪽 값이 같음
[ !=, <> ] === 양쪽 값이 다름
[ >, < ] ===(왼쪽, 오른쪽) 값이 더 큼
[ >=, <= ] === (왼쪽, 오른쪽) 값이 같거나 더 큼
[ BETWEEN {MIN} AND {MAX} ] === 두 값 사이에 있음
[ NOT BETWEEN {MIN} AND {MAX} ] === 두 값 사이가 아닌 곳에 있음
[ IN (...)] === 괄호 안의 값들 가운데 있음
[ NOT IN (...) ] === 괄호 안의 값들 가운데 없음
[ LIKE '... % ...' ] === 0~N개 문자를 가진 패턴
[ LIKE '... _ ...' ] === _ 갯수만큼의 문자를 가진 패턴
*/
※ 예시가 너무 방대하여 이해가 난해한 경우만 간략한 예시를 작성했다. ※
Math
- ROUND = 반올림
CEIL = 올림
FLOOR = 내림 - ABS = 절대값
- GREATEST() = 가장 큰 값
- LEAST() = 가장 작은 값
- MAX() = 가장 큰 값
MIN() = 가장 작은 값
COUNT() = 갯수 (NULL값 제외)
SUM() = 총합
AVG() = 평균 값 - TRUNCATE(N, n) = N을 소숫점 n자리까지 선택
문자열 케이스
- UCASE, UPPER = 모두 대문자로
LCASE, LOWER = 모두 소문자로 - CONCAT(...) = 괄호 안의 인자(내용)를 이어붙임
SELECT CONCAT('HELLO', ' ', 'THIS IS ', 2021)
= (HELLO THIS IS 2021) 숫자도 문자열로 자동변환되어 더해진다.
CONCAT_WS(S, ...) = 첫번째 인자로 이어붙임
SELECT CONCAT_WS('-', 2021, 8, 15, 'AM')
= (2021-8-15-AM) - SUBSTR(), SUBSTRING() = 주어진 값에 따라 문자열 자름
SELECT
SUBSTR('ABCDEFG', 3),
= 왼쪽에서 3번째 문자부터 읽어온다. (CDEFG)
LEFT() = 왼쪽부터 N글자
RIGHT() = 오른쪽부터 N글자
그룹함수
1. 예시
SELECT Country FROM Customers
GROUP BY Country;
-- 중복되는 것들을 모두 하나로 묶어서 하나씩만 보여진다.
SELECT
Country, City,
CONCAT_WS(', ', City, Country) as 'city, country'
FROM Customers
GROUP BY Country, City;
-- GROUP BY를 컨트리와 시티에 해주어서 Country의 값이 같은
-- 값이라도 City의 값이 다르면 다 보여준다.
2. 그룹함수 활용하기
SELECT
COUNT(*), OrderDate
FROM Orders
GROUP BY OrderDate;
-- 그룹으로 묶인 값들의 갯수도 같이 볼 수 있다.
SELECT
ProductID,
SUM(Quantity) AS QuantitySum
FROM OrderDetails
GROUP BY ProductID
ORDER BY QuantitySum DESC;
SELECT
CategoryID,
MAX(Price) AS MaxPrice,
MIN(Price) AS MinPrice,
TRUNCATE((MAX(Price) + MIN(Price)) / 2, 2) AS MedianPrice,
TRUNCATE(AVG(Price), 2) AS AveragePrice
FROM Products
GROUP BY CategoryID;
SELECT
CONCAT_WS(', ', City, Country) AS Location,
COUNT(CustomerID)
FROM Customers
GROUP BY Country, City;
Tryit Editor을 통해서 사용해보면 결과값을 확인할 수 있다.
- WITH ROLLUP = 전체의 집계값 (ORDER BY와는 사용불가능)
SELECT
Country, COUNT(*)
FROM Suppliers
GROUP BY Country
WITH ROLLUP;
-- COUNT의 합계가 가장 밑에 추가된다.
- HAVING = 그룹화된 데이터 걸러내기
SELECT
Country, COUNT(*) AS Count
FROM Suppliers
GROUP BY Country
HAVING Count >= 3;
-- Count로 집계된 데이터중 3과 같거나 큰 값만 보여준다.
- WHERE는 그룹하기 전 데이터, HAVING은 그룹 후 집계에 사용한다.
SELECT
COUNT(*) AS Count, OrderDate
FROM Orders
WHERE OrderDate > DATE('1996-12-31')
GROUP BY OrderDate
HAVING Count > 2;
-- WHERE로 1996-12-31보다 높은 수의 날짜들로 거른 후
-- OrderDate를 그룹화 시켜준 후 그룹화가 되었으니 HAVING으로 2보다 높은 수만 보여준다.
SELECT
CategoryID,
MAX(Price) AS MaxPrice,
MIN(Price) AS MinPrice,
TRUNCATE((MAX(Price) + MIN(Price)) / 2, 2) AS MedianPrice,
TRUNCATE(AVG(Price), 2) AS AveragePrice
FROM Products
WHERE CategoryID > 2
GROUP BY CategoryID
HAVING
AveragePrice BETWEEN 20 AND 30
AND MedianPrice < 40;
-- 이와같은 예시로 WHERE로 먼저 데이터를 걸러준 후 GROUP BY를
-- 사용해서 묶어준 후 HAVING으로 걸러낼 수 있다.
- DISTINCT = 중복된 값들을 제거한다.
GROUP BY 와 달리 집계함수가 사용되지 않는다.
GROUP BY 와 달리 정렬하지 않으므로 더 빠르다.
SELECT DISTINCT CategoryID
FROM Products;
-- 위의 GROUP BY를 사용한 쿼리와 결과 비교
-- GROUP BY는 오름차순(Default)으로 정렬되어 보여주지만 DISTINCT는
-- 정렬하지 않은채로 데이터를 보여준다.
SELECT COUNT DISTINCT CategoryID
FROM Products;
-- 오류 발생
-- DISTINCT는 집계함수를 사용할 수 없어서 오류가 발생한다.
- GROUP BY와 DISTINCT 함께 활용
SELECT
Country,
COUNT(DISTINCT CITY)
FROM Customers
GROUP BY Country;
-- 그룹으로 묶어줄때 집계함수 내부에 포함시켜 줄 수 있다.
마치며...
포스팅을 하다보니 너무 방대해서 포스팅을 나눠서 해야할 필요성을 느껴, 이만작성하고 다음 포스팅에서 상관 서브쿼리와 비상관 서브쿼리, JOIN 등에 대해서 포스팅을 마저 해야겠다.
예시자료 출처 - https://www.yalco.kr/lectures/sql/
'Backend > MySQL' 카테고리의 다른 글
[ MySQL ] 상관,비상관 서브쿼리와 JOIN (0) | 2023.02.02 |
---|---|
[ MySQL ] 데이터베이스 (4) | 2023.01.29 |