[ᴘʀᴏɢʀᴀᴍᴍᴇʀꜱ] SQL - 데이터 조회(SELECT, WHERE, ORDER BY)

NewHa·2023년 11월 5일
1
post-thumbnail

☀️ SELECT

SELECT 필드(컬럼) FROM 테이블명;
  • 테이블의 데이터를 조회할 때 사용하는 구문으로 모든 SQL 코딩 테스트 문제는 SELECT 부터 시작합니다.
  • 테이블로부터(from) 필드의 데이터(필드, column)를 가져오겠다(select)는 뜻입니다.
  • 이때 필드위치에 *(asterisk)를 쓰면 모든 필드라는 뜻으로 각 row의 모든 column 값을 조회할 수 있습니다. 특정 필드(컬럼)명을 넣어 해당 필드만 조회할 수도 있습니다.
  • FROM은 '~로 부터'의 뜻으로, 어느 테이블로부터 데이터를 조회할 것인지를 나타내기 위해 사용합니다.

AS

alias의 줄임말로 컬럼에 별명, 별칭을 붙이는 것입니다.

SELECT 컬럼명 AS 별칭(새컬럼명) FROM 테이블명;
SELECT 컬럼명 별칭(새컬럼명) FROM 테이블명;
-- AS를 빼고 한칸 띄어써도 똑같이 작용하지만, 가독성을 위해 AS를 작성하는 것을 권장합니다.


☀️ WHERE

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

🪴 여러 조건을 걸 때 주의할 점


  1. OR 사용 시에 만약 age = 20 OR age = 30 이런 조건문이라면, age = 20 OR 30이라고 축약해서 사용할 수 없습니다. 이는 age = 20 이거나 그냥 데이터가 30 인 경우를 나타내는데, MySQL에서는 0(false)이외의 모든 숫자는 true로 간주되어 30이라는 조건은 모든 경우가 참인 경우가 됩니다.
  2. AND가 OR보다 우선순위가 높아서 먼저 실행되는 점의 주의해야 합니다. 따라서 명확하게 하기 위해 먼저 실행되길 원하는 조건은 괄호()를 씌워서 우선순위를 높여주고 관계를 명확히 해주는 것이 좋습니다.

BETWEEN A AND B

위의 예시를 더 직관적으로 표현해 조회할 수 있습니다.

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 조건문은 연속적인 값에서만 사용할 수 있어서 연속적이지 않은 값들을 조회할 때는 사용할 수 없습니다.

IN

'이 중에 있는~' 이라는 뜻으로 연속적이지 않은 이산 값들에서 조건에 해당하는 값이 있는 row만 을 조회하고 싶을 때는 IN 조건 표현식을 사용할 수 있습니다.

-- 예를 들어, address가 '서울'이거나 '경기'인 사람만 조회하고 싶으면 다음과 같이 적을 수 있다.
WHERE address IN ('서울', '경기');

🌿 문자열 패턴 매칭 조건

LIKE 연산자

LIKE 연산자를 활용해 특정 패턴을 포함하는 데이터를 찾아낼 수 있습니다. 와일드카드 문자를 활용해 임의의 문자나 문자열을 대체해 특정 패턴을 포함하는 데이터를 찾아낼 수 있습니다. 와일드카드로는 %_이 있습니다.

  • % : 0개 이상의 문자를 대체해 부분일치 문자열을 찾습니다.
WHERE address LIKE '서울%';
-- 이라고 하면 주소가 '서울'로 시작하는 임의의 길이를 가지는 문자열을 필터링한다.

WHERE address LIKE '%동작구%';
-- 이라고 하면 주소 중간에 '동작구'를 포함하는 문자열을 조회한다.

WHERE address LIKE '%101호';
-- 이라고하면 주소 끝이 '101호'로 끝나는 문자열을 조회한다.

🫥 프로그래머스 SQL 코딩테스트 - 경기도에 위치한 식품창고 목록 출력하기 (lv.1)

  • '경기도 안산시 상록구 용담로 141' 이러한 형태의 주소를 가지는 필드에서 경기도에 위치한 창고만 조회해야 합니다.
WHERE address like "%경기%"
  • _ : 1개의 문자를 대체합니다.
WHERE name LIKE '김__';
-- 이라고 하면 성이 '김'이고 이름이 세글자인 데이터만을 필터링한다.

🪴 문자열 패턴 매칭 조건시 주의할 점


  1. escaping(이스케이핑) 문제
  • 어떤 문자가 부여된 특정한 의미나 기능이 아닌 단순한 일반 문자 하나로 해석되도록 취급하는 행위를 escaping(이스케이핑)이라고 합니다.
    값에 %, ', _, " 와 같은 문자들이 있다면 일반 문자임과 동시에 어떤 문자열임을 나타내는 ' ', " " 것 이거나, 문자열의 특정 패턴을 나타내는 %, _ 표현식입니다.
  • 만약 '%' 기호가 포함된 값을 찾는다고 LIKE '%%%'이라고 조건을 적으면 정가운데 문자도 표현식으로 간주되어 모든 문자열이 조회됩니다. 따라서 이럴 땐 문자임을 알려주기위해 \(역슬래쉬)를 사용합니다. (LIKE '%\%%')
  1. 대소문자 구분 문제
  • MySQL의 기본설정은 대소문자를 구분하지 않습니다. 이는 기본설정 > 테이블 설정에서 문자열이 서로 동일한지 비교할 때 적용되는 설정인 'Table collation'항목이 'utf8mb4_0900_ai_ci' 값을 기본으로 가지기 때문입니다. 여기서 'ci'란 'case-insensitive'의 약자로, 대소문자를 구분하지 않겠다는 뜻입니다.
  • 실무에서 데이터베이스 관리자가 아니라면 이러한 설정을 바꿀 권한이 없습니다. 이럴 때 대소문자를 구분하기위해 BINARY 키워드를 사용할 수 있습니다. 이는 '이진의, 0과 1로 된' 이라는 뜻으로, 문자를 이진 값으로 치완하여 이진 값과 같은 수준까지 문자열을 비교하라는 뜻을 부여합니다.


☀️ DATE 타입

🌿 연, 월, 일 추출

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)

🌿 UNIX TIMESTAMP()

1970년 01월 01일을 기준으로 몇 초가 지났는지를 나타내어 날짜 및 시간을 나타내는 값입니다. 날짜 필드에서 이런 숫자로 된 값을 본다면 FROM_UNIXTIME() 함수를 사용해 날짜 형식을 바꾸어 줄 수 있습니다.

FROM_UNIXTIME(UNIX_TIMESTAMP(birthday))
-- 이렇게 하면 '년.월.일. 00:00:00' 이라고 시간정보까지 포함되어 나온다.

UNIX TIMESTAMP 시간을 사용하면 기준시간으로 부터 초를 잰 숫자값이므로 여러 계산을 하기가 편해집니다. 따라서 TIMESTAMPDIFF() 함수를 사용해 여러 형태의 계산을 할 수 있습니다.

SELECT TIMESTAMPDIFF(반환 값 형식, CURDATE() ,birthday)
-- 반환 값 형식으로 MONTH, YEAR, HOUR 등의 값을 넣어 원하는 값을 얻을 수 있어 용이하다.

🌿 DATE_FORMAT

날짜, 시간을 지정한 형식으로 출력케 하는 함수입니다.

-- 보통은 '2023-12-31 00:00:00' 과 같은 형식을 '2023-12-31'형식으로 출력케 한다.
SELECT DATE_FORMAT(DATETIME, '%Y-%m-%d')
  • 대 소문자 별로 출력 형식이 다름을 주의해야 하고, 더 다양한 시간 형식은 MySQL DATE_FORMAT() Function 👈🏻 여기에서 확인할 수 있지만, 코딩테스트에서 원하는 형식은 일정하므로 너무 깊게 파지는 맙시다!!🙄

🫥 프로그래머스 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'으로 표현되기 때문입니다.


☀️ ORDER BY

🌿 데이터 정렬해 보기

SELECT 필드명 FROM 테이블명
WHERE 조건식
ORDER BY 정렬기준필드 ASC|DESC;
  • 테이블의 row들을 원하는 특정 기준으로 순서대로 정렬하여 출력할 수 있습니다.
  • 기본적으로 오름차순인 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 타입을 사용하면 된다.


☀️ LIMIT

SELECT 필드명 FROM 테이블명
WHERE 조건식
ORDER BY 정렬기준필드 ASC|DESC
LIMIT 제한할 갯수;
  • 출력하는 데이터의 개수를 제한하여 일부만 추려볼 수 있습니다. 쉽게 말하자면 데이터가 1억개라면 그 중 상위 50개만 불러와서 출력하는 것입니다. 이렇게 출력을 제한하면 데이터베이스의 부담을 줄여줄 수 있습니다.
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

👀 Reference

profile
백 번을 보면 한 가지는 안다 👀

0개의 댓글