SELECT 필드(컬럼) FROM 테이블명;
from
) 필드의 데이터(필드
, column
)를 가져오겠다(select
)는 뜻입니다.*
(asterisk)를 쓰면 모든 필드라는 뜻으로 각 row의 모든 column 값을 조회할 수 있습니다. 특정 필드(컬럼)명을 넣어 해당 필드만 조회할 수도 있습니다.alias의 줄임말로 컬럼에 별명, 별칭을 붙이는 것입니다.
SELECT 컬럼명 AS 별칭(새컬럼명) FROM 테이블명; SELECT 컬럼명 별칭(새컬럼명) FROM 테이블명; -- AS를 빼고 한칸 띄어써도 똑같이 작용하지만, 가독성을 위해 AS를 작성하는 것을 권장합니다.
SELECT 필드 FROM 테이블명 WHERE 조건식;
조회문에 특정 조건을 추가해 조건을 만족하는 원하는 데이터(row)만 조회할 수 있는데, 이러한 조건을 설정할 때 WHERE문을 사용합니다.
WHERE문 뒤에는 다양한 연산자를 사용할 수 있습니다.
=
, <
, >
, <=
, >=
과 같은 기호들이 존재합니다.
--예를 들어, 조건연산자로 AGE가 30세 이상인 사람만을 조회하고 싶다면 다음과 같이 적는다.
WHERE age >= 30
🫥 프로그래머스 SQL 코딩테스트 - 어린 동물 찾기 (lv.1)
INTAKE_CONDITION
이 Aged가 아닌 경우를 조회하는 sql을 작성하는 문제로 WHERE문을 사용해 조건을 만족하는 데이터만 조회할 수 있습니다.SELECT animal_id, name FROM animal_ins WHERE intake_condition != 'Aged'
!=
, <>
은 같지 않다는 표현식으로 '~이 아닌'이라는 조건에 쓰일 수 있습니다.
-- 예를 들어, 남자가 아닌 여성만 조회하는 조건문을 적게된다면 다음과 같다.
WHERE gender != 'man';
-- 혹은
WHERE gender <> 'man';
OR
, AND
, NOT
을 사용해 더 다양하고 여러개의 조건을 만들 수 있습니다.
-- 예를 들어, age가 30대인 사람만 조회하고 싶다면 다음과 같이 적을 수 있다.
WHERE age >= 30 AND age < 40
🪴 여러 조건을 걸 때 주의할 점
- OR 사용 시에 만약
age = 20 OR age = 30
이런 조건문이라면,age = 20 OR 30
이라고 축약해서 사용할 수 없습니다. 이는age = 20
이거나 그냥 데이터가30
인 경우를 나타내는데, MySQL에서는0
(false)이외의 모든 숫자는 true로 간주되어30
이라는 조건은 모든 경우가 참인 경우가 됩니다.- AND가 OR보다 우선순위가 높아서 먼저 실행되는 점의 주의해야 합니다. 따라서 명확하게 하기 위해 먼저 실행되길 원하는 조건은 괄호
()
를 씌워서 우선순위를 높여주고 관계를 명확히 해주는 것이 좋습니다.
위의 예시를 더 직관적으로 표현해 조회할 수 있습니다.
WHERE age BETWEEN 30 AND 39;
🫥 프로그래머스 SQL 코딩테스트 - 조건에 맞는 회원수 구하기 (lv.1)
- 2021년에 가입했다는 조건과 나이가 20세 이상 29세 이하라는 두 가지 조건문을 작성해야 합니다.
WHERE (YEAR(joined) = '2021') AND (age BETWEEN 20 AND 29)
하지만 BETWEEN A AND B
조건문은 연속적인 값에서만 사용할 수 있어서 연속적이지 않은 값들을 조회할 때는 사용할 수 없습니다.
'이 중에 있는~' 이라는 뜻으로 연속적이지 않은 이산 값들에서 조건에 해당하는 값이 있는 row만 을 조회하고 싶을 때는 IN
조건 표현식을 사용할 수 있습니다.
-- 예를 들어, address가 '서울'이거나 '경기'인 사람만 조회하고 싶으면 다음과 같이 적을 수 있다.
WHERE address IN ('서울', '경기');
LIKE 연산자를 활용해 특정 패턴을 포함하는 데이터를 찾아낼 수 있습니다. 와일드카드 문자를 활용해 임의의 문자나 문자열을 대체해 특정 패턴을 포함하는 데이터를 찾아낼 수 있습니다. 와일드카드로는 %
와 _
이 있습니다.
%
: 0개 이상의 문자를 대체해 부분일치 문자열을 찾습니다.WHERE address LIKE '서울%';
-- 이라고 하면 주소가 '서울'로 시작하는 임의의 길이를 가지는 문자열을 필터링한다.
WHERE address LIKE '%동작구%';
-- 이라고 하면 주소 중간에 '동작구'를 포함하는 문자열을 조회한다.
WHERE address LIKE '%101호';
-- 이라고하면 주소 끝이 '101호'로 끝나는 문자열을 조회한다.
🫥 프로그래머스 SQL 코딩테스트 - 경기도에 위치한 식품창고 목록 출력하기 (lv.1)
- '경기도 안산시 상록구 용담로 141' 이러한 형태의 주소를 가지는 필드에서 경기도에 위치한 창고만 조회해야 합니다.
WHERE address like "%경기%"
_
: 1개의 문자를 대체합니다.WHERE name LIKE '김__';
-- 이라고 하면 성이 '김'이고 이름이 세글자인 데이터만을 필터링한다.
🪴 문자열 패턴 매칭 조건시 주의할 점
- escaping(이스케이핑) 문제
- 어떤 문자가 부여된 특정한 의미나 기능이 아닌 단순한 일반 문자 하나로 해석되도록 취급하는 행위를 escaping(이스케이핑)이라고 합니다.
값에%
,'
,_
,"
와 같은 문자들이 있다면 일반 문자임과 동시에 어떤 문자열임을 나타내는 ' ', " " 것 이거나, 문자열의 특정 패턴을 나타내는 %, _ 표현식입니다.- 만약 '%' 기호가 포함된 값을 찾는다고
LIKE '%%%'
이라고 조건을 적으면 정가운데 문자도 표현식으로 간주되어 모든 문자열이 조회됩니다. 따라서 이럴 땐 문자임을 알려주기위해\
(역슬래쉬)를 사용합니다. (LIKE '%\%%'
)
- 대소문자 구분 문제
- MySQL의 기본설정은 대소문자를 구분하지 않습니다. 이는 기본설정 > 테이블 설정에서 문자열이 서로 동일한지 비교할 때 적용되는 설정인 'Table collation'항목이 'utf8mb4_0900_ai_ci' 값을 기본으로 가지기 때문입니다. 여기서 'ci'란 'case-insensitive'의 약자로, 대소문자를 구분하지 않겠다는 뜻입니다.
- 실무에서 데이터베이스 관리자가 아니라면 이러한 설정을 바꿀 권한이 없습니다. 이럴 때 대소문자를 구분하기위해
BINARY
키워드를 사용할 수 있습니다. 이는 '이진의, 0과 1로 된' 이라는 뜻으로, 문자를 이진 값으로 치완하여 이진 값과 같은 수준까지 문자열을 비교하라는 뜻을 부여합니다.
YEAR
, HOUR
, MONTH
, DAY
... : 날짜와 관련된 필드에서 원하는 데이터의 일부(년, 월, 일, 시, 분, 초 등)를 추출할 수 있습니다.
-- YEAR을 사용해 연도만 조회해 1992년에 태어난 사람들만 필터링할 수 있다.
WHERE YEAR(birthday) = '1992';
-- MONTH를 사용해 6, 7, 8월에 태어난 사람들만 필터링 할 수 있다.
WHERE MONTH(birthday) IN (6, 7, 8);
-- DAYOFMONTH 함수로 일만 조회해 월 초에 태어난 사람들만 필터링할 수 있다.
WHERE DAYOFMONTH(birthday) BETWEEN 1 AND 10;
DATEDIFF(날짜A, 날짜B)
= 날짜A - 날짜B 를 해서 날짜 간 차이 일수를 알려줍니다.
CURDATE()
함수를 사용하면 오늘 날짜를 구하는 것도 가능합니다.
-- 따라서 더 뒤의 날짜를 A위치에 적어야 한다. 이를 통해 태어난 날로부터 몇일 째인지를 구할 수 있다.
SELECT DATEDIFF(CURDATE(), birthday);
이 외에 PERIOD_DIFF()
함수를 사용하면 기간 사이의 개월 수를 계산할 수 있고, TIMESTAMPDIFF()
함수를 사용해 두 기간 사이의 시간도 계산할 수 있습니다.
DATE_ADD()
, DATE_SUB()
을 이용해서 날짜 간 연산을 할 수 있습니다.
-- 태어난 날을 기준으로 100일 이후의 날짜를 구할 수 있다.
SELECT DATE_ADD(birthday, INTERVAL 100 DAY)
-- 태어나기 300일 전의 날짜를 구할 수 있다.
SELECT DATE_SUB(birthday, INTERVAL 300 DAY)
1970년 01월 01일을 기준으로 몇 초가 지났는지를 나타내어 날짜 및 시간을 나타내는 값입니다. 날짜 필드에서 이런 숫자로 된 값을 본다면 FROM_UNIXTIME()
함수를 사용해 날짜 형식을 바꾸어 줄 수 있습니다.
FROM_UNIXTIME(UNIX_TIMESTAMP(birthday))
-- 이렇게 하면 '년.월.일. 00:00:00' 이라고 시간정보까지 포함되어 나온다.
UNIX TIMESTAMP 시간을 사용하면 기준시간으로 부터 초를 잰 숫자값이므로 여러 계산을 하기가 편해집니다. 따라서 TIMESTAMPDIFF()
함수를 사용해 여러 형태의 계산을 할 수 있습니다.
SELECT TIMESTAMPDIFF(반환 값 형식, CURDATE() ,birthday)
-- 반환 값 형식으로 MONTH, YEAR, HOUR 등의 값을 넣어 원하는 값을 얻을 수 있어 용이하다.
날짜, 시간을 지정한 형식으로 출력케 하는 함수입니다.
-- 보통은 '2023-12-31 00:00:00' 과 같은 형식을 '2023-12-31'형식으로 출력케 한다.
SELECT DATE_FORMAT(DATETIME, '%Y-%m-%d')
🫥 프로그래머스 SQL 코딩테스트 - DATETIME에서 DATE로 형 변환 (lv.2)
- 각 동물의 아이디와 이름, 들어온 날짜를 조회하는 SQL문을 작성하되, 들어온 날짜를 시각(시-분-초)을 제외한 날짜(년-월-일)만 보이도록 출력하는 문제입니다.
SELECT animal_id, name, DATE_FORMAT(datetime, "%Y-%m-%d") FROM animal_ins
- 제가 여태 풀어본 문제들은 대부분 'YYYY-mm-dd'형식으로 출력하는 문제였습니다. 따라서
%Y-%m-%d
의 형식을 기억해 놓으면 대부분의 문제가 풀립니다.- 여기서 'Y'는 반드시 대문자여야 합니다.
%Y
는 '2023'으로 표시되고,%y
는 '23'으로 표현되기 때문입니다.
SELECT 필드명 FROM 테이블명 WHERE 조건식 ORDER BY 정렬기준필드 ASC|DESC;
ASC
가 적용되고, 내림차순의 경우 DESC
를 더해줍니다.🫥 프로그래머스 SQL 코딩테스트 - 동물의 아이디와 이름 (lv.1)
- 동물의 아이디와 이름을 ANIMAL_ID순으로 조회하는 쿼리문을 작성하는 문제입니다. (default 는 ASC이므로 적지 않아도 적용됩니다.)
SELECT animal_id, name FROM animal_ins ORDER BY animal_id
🫥 프로그래머스 SQL 코딩테스트 - 역순 정렬하기 (lv.1)
- 동물의 이름과 보호 시작일을 조회하면서 결과는 ANIMAL_ID 역순으로 출력하는 쿼리문을 작성하는 문제입니다.
SELECT name, datetime FROM animal_ins ORDER BY animal_id DESC
정렬 기준의 데이터 타입이 숫자형인 경우와, 문자열인 경우에 정렬결과가 달라집니다.
여기서는 컬럼의 타입이 문자타입이지만 값이 숫자인 경우, 숫자형 타입으로 보고 정렬하는 방법을 서술합니다.
CAST()
는 '틀을 만들다, 정하다'의 뜻을 가지는 함수로, 어떤 변수의 데이터 타입을 바꿀 때 사용됩니다. 타입은 문자이지만 값이 숫자인 경우, 일시적으로 타입을 변환하여 정렬할 수 있습니다.
ORDER BY CAST(컬럼명 AS signed);
-- 이라고 하면 해당 컬럼의 문자타입의 숫자 값을 일시적으로 signed라는 데이터타입으로 변환하라는 뜻이다.
-- signed는 양수와 음수를 포함한 모든 정수를 나타내는 데이터타입을 말한다.
-- 만약 소수점이 있는 수라면 decimal 타입을 사용하면 된다.
SELECT 필드명 FROM 테이블명 WHERE 조건식 ORDER BY 정렬기준필드 ASC|DESC LIMIT 제한할 갯수;
LIMIT 10;
-- 뒤에 숫자를 하나만 적으면 해당 수만큼의 데이터를 출력해달라는 뜻이다. 따라서 10개의 데이터만 불러온다.
OFFSET
을 사용해서 어디서부터 어디까지로 범위를 지정해서 데이터를 출력할 수도 있습니다.LIMIT 5 OFFSET 3;
-- 이렇게 하면 3번째 데이터에서부터 5개의 데이터를 불러옵니다. (이 때 row는 0부터 시작한다.)
-- OFFSET은 생략해서 사용할 수도 있습니다.
LIMIT 5, 3;
🫥 프로그래머스 SQL 코딩테스트 - 상위 n개 레코드 (lv.1)
- 가장 먼저 들어온 동물의 이름을 조회하기 때문에 딱 한개의 데이터만 불러오면 되는 문제입니다.
SELECT name FROM animal_ins ORDER BY datetime LIMIT 1