SELECT - MySQL 풀이

송철진·2023년 3월 16일
0

프로그래머스-MySQL

목록 보기
1/7

Lv.1

동물의 아이디와 이름

SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
ORDER BY ANIMAL_ID

모든 동물의 아이디와 이름을 ANIMAL_ID순으로 조회하려면
ORDER BY구문을 사용한다. 기본값이 오름차순이므로 ASC는 생략할 수 있다.

SQL ORDER BY Keyword
The ORDER BY keyword sorts the records in ascending order by default.
To sort the records in descending order, use the DESC keyword.

SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;

역순 정렬하기

SELECT NAME, DATETIME
FROM ANIMAL_INS
ORDER BY ANIMAL_ID DESC

ANIMAL_ID 역순으로 👉 DESC

여러 기준으로 정렬하기

SELECT ANIMAL_ID, NAME, DATETIME
FROM ANIMAL_INS
ORDER BY NAME, DATETIME DESC

여러 기준으로 정렬할 땐 ORDER BY와 각 기준 컬럼을 콤마(,)로 구분한다.
우선적으로 정렬할 기준 컬럼을 먼저 작성한다. NAME이 동일하면 DATETIME이 나중인 순으로 정렬해야 하므로 NAME을 먼저 입력했다.

인기있는 아이스크림

SELECT FLAVOR
FROM FIRST_HALF
ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID

상반기에 판매된 아이스크림의 맛을 총주문량을 기준으로 내림차순 정렬하고
총주문량이 같다면 출하 번호를 기준으로 오름차순 정렬

상위 n개 레코드

SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1

가장 먼저 들어온 동물의 이름을 조회하려면
날짜 오름차순으로 정렬하고, 1개로 제한한다.

MySQL LIMIT Clause
The LIMIT clause is used to specify the number of records to return.
The LIMIT clause is useful on large tables with thousands of records. Returning a large number of records can impact performance.

SELECT column_name(s)
FROM table_name
WHERE condition
LIMIT number;

어린 동물 찾기

SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION != 'Aged'

또는 WHERE INTAKE_CONDITION <> 'Aged' 라고 쓸 수 있다.

WHERE 절의 Operators
=, >, <, >=, <=, <>(다름. 일부 버전에서는 !=),
BETWEEN(범위), LIKE(패턴 검색), IN(컬럼에 여러 값 지정하기)

강원도에 위치한 생산공장 목록

SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '강원도%'

강원도에 위치한 식품공장의 공장 ID, 공장 이름, 주소를 조회하기
주소가 강원도로 시작하는 값을 찾으면 되므로 LIKE 연산자를 사용했다.

SQL LIKE Operator
https://www.w3schools.com/sql/sql_like.asp
WHERE CustomerName LIKE 'a%' a로 시작하는 값
WHERE CustomerName LIKE '%a' a로 끝나는 값
WHERE CustomerName LIKE '%or%' or가 들어가는 값
WHERE CustomerName LIKE '_r%' r이 2번째 글자로 들어가는 값
WHERE CustomerName LIKE 'a_%' a로 시작하는 최소 2글자인 값
WHERE CustomerName LIKE 'a__%' a로 시작하는 최소 3글자인 값
WHERE ContactName LIKE 'a%o' a로 시작해서 o로 끝나는 값

모든 레코드 조회하기

SELECT *
FROM ANIMAL_INS
ORDER BY ANIMAL_ID

SELECT 문과 함께 별표(*) 기호를 사용하면
해당 테이블의 모든 필드를 선택할 수 있다.

조건에 맞는 회원수 구하기

SELECT COUNT(*) AS USERS
FROM USER_INFO
WHERE JOINED LIKE '2021%' AND (AGE >= 20 AND AGE <= 29)

COUNT(컬럼) 함수
테이블에서 컬럼 데이터 개수를 가져오는 함수

조건에 부합하는 중고거래 댓글 조회

SELECT
    ugb.TITLE,	
    ugb.BOARD_ID,	
    ugr.REPLY_ID,	
    ugr.WRITER_ID,	
    ugr.CONTENTS,	
    LEFT(ugr.CREATED_DATE, 10) as CREATED_DATE
FROM USED_GOODS_BOARD ugb
INNER JOIN USED_GOODS_REPLY ugr 
ON ugb.BOARD_ID = ugr.BOARD_ID
WHERE LEFT(ugb.CREATED_DATE, 10) LIKE '2022-10%' 
ORDER BY ugr.CREATED_DATE, ugb.TITLE
  1. 테이블: USED_GOODS_BOARD, USED_GOODS_REPLY
  2. 조건: 2022년 10월에 작성된 게시글
  3. 조회 컬럼: 게시글 제목, 게시글 ID, 댓글 ID, 댓글 작성자 ID, 댓글 내용, 댓글 작성일

문제는 단순하지만 문제를 잘못 읽거나 ugb, ugr을 헷갈려서 다소 시간이 걸렸다.
정해진 정답은 없고 이외에도 구글링해보면 다양한 방법이 있는 거 같다.

예)

SELECT
	SUBSTRING_INDEX(ugr.CREATED_DATE, ' ', 1) as CREATED_DATE

MySQL 문자열 자르기 함수
https://redcow77.tistory.com/264
SUBSTING(문자열, 시작위치) 👉 첫번째 글자의 위치는 1 이다.
SUBSTING(문자열, 시작위치, 길이)
SUBSTING(문자열 FROM 시작위치)
SUBSTING(문자열 FROM 시작위치 FOR 길이)
LEFT(문자열, 길이) 👉 왼쪽 기준
RIGHT(문자열, 길이) 👉 오른쪽 기준
SUBSTRING_INDEX(문자열, 구분자, 구분자index)

DATE_FORMAT
https://devjhs.tistory.com/89

흉부외과 또는 일반외과 의사 목록

SELECT 
    DR_NAME, 
    DR_ID, 
    MCDP_CD, 
    DATE_FORMAT(HIRE_YMD, '%Y-%m-%d') AS HIRE_YMD
FROM DOCTOR
WHERE MCDP_CD IN ('CS', 'GS')
ORDER BY HIRE_YMD DESC, DR_NAME 

DATE_FORMAT(날짜, 형식)
년 - %Y 2023 %y 23
월 - %m 01 ~ 12 %c 1 ~ 12
월 - %M January ~ December %b Jan ~ Dec
일 - %d 01 ~ 31 %e 1 ~ 31
요일 - %W Sunday ~ Saturday %a Sun ~ Sat
시 - %I, %h 00 ~ 12
시 - %H 00 ~ 23 %k 0 ~ 23
분 - %i 00 ~ 59
초 - %S 00 ~ 59
시분초 - %r hh:mm:ss AM,PM %T hh:mm:SS
n일째 - %j 001 ~ 366 %w 0(일) ~ 6(토)
n번째 주 - %U 한 해의 00~54번째 주(주: 일~토) %u 01~54(주: 월~일)
그 주가 시작된~ - %X 년, %V n번째 주 (주: 일~토)
그 주가 시작된~ - %x 년, %v n번째 주 01~53(주: 월~일)

조건에 맞는 도서 리스트

SELECT 
    BOOK_ID, 
    DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK
WHERE PUBLISHED_DATE LIKE '2021%' AND CATEGORY = '인문'
ORDER BY PUBLISHED_DATE

FROM - BOOK 테이블에서
WHERE - 2021년에 출판된 '인문' 카테고리에 속하는 도서 리스트를 찾아서
SELECT - 도서 ID(BOOK_ID), 출판일 (PUBLISHED_DATE)을 출력
ORDER BY - 결과는 출판일을 기준으로 오름차순 정렬

과일로 만든 아이스크림

SELECT ii.FLAVOR
FROM ICECREAM_INFO ii
INNER JOIN FIRST_HALF fh ON ii.FLAVOR = fh.FLAVOR
WHERE fh.TOTAL_ORDER > 3000 AND ii.INGREDIENT_TYPE = 'fruit_based'
ORDER BY TOTAL_ORDER DESC

WHERE

  • 상반기 아이스크림 총주문량이 3,000보다 높으면서
  • 아이스크림의 주 성분이 과일인

SELECT

  • 아이스크림의 맛을

ORDER BY

  • 총주문량이 큰 순서대로

12세 이하인 여자 환자 목록

PATIENT 테이블에서 12세 이하인 여자환자의 환자이름, 환자번호, 성별코드, 나이, 전화번호를 조회하는 SQL문을 작성해주세요. 이때 전화번호가 없는 경우, 'NONE'으로 출력시켜 주시고 결과는 나이를 기준으로 내림차순 정렬하고, 나이 같다면 환자이름을 기준으로 오름차순 정렬해주세요.

SELECT 
    PT_NAME, 
    PT_NO, 
    GEND_CD, AGE, 
    COALESCE(TLNO, 'NONE') AS TLNO
FROM PATIENT
WHERE AGE <= 12 AND GEND_CD = 'W'
ORDER BY AGE DESC, PT_NAME

코얼레스.. 합치다.

COALESCE(컬럼, '값') 함수
컬럼이 null 이면 '값'으로 대체하는 함수

평균 일일 대여 요금 구하기

CAR_RENTAL_COMPANY_CAR 테이블에서
자동차 종류가 'SUV'인 자동차들의 평균 일일 대여 요금을 출력
이때 평균 일일 대여 요금은 소수 첫 번째 자리에서 반올림하고,
컬럼명은 AVERAGE_FEE

SELECT ROUND(AVG(DAILY_FEE)) AS AVERAGE_FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE = 'SUV'

평균 AVG() 함수

반올림 ROUND() 함수

  • 소수점 1번째 자리에서 : ROUND(컬럼)
  • 소수점 2번째 자리에서 : ROUND(컬럼, 1)
  • 1의 자리에서 : ROUND(컬럼, -1)

버림 TRUNCATE(), FLOOR() 함수

  • 소수점 아래 : FLOOR(컬럼)
  • 특정 자릿수에서 : TRUNCATE(컬럼, 자릿수)

Lv.2

재구매가 일어난 상품과 회원 리스트

SELECT a.USER_ID, a.PRODUCT_ID
FROM (
    SELECT USER_ID, PRODUCT_ID, COUNT(*) AS COUNT
    FROM ONLINE_SALE
    GROUP BY USER_ID, PRODUCT_ID
) AS a
WHERE a.COUNT > 1
ORDER BY USER_ID, PRODUCT_ID DESC

USER_ID, PRODUCT_ID를 기준으로 그룹핑해서 행의 개수 COUNT를 구한 테이블을 a라고 할 때, COUNT가 1보다 큰 경우에만 a.USER_ID, a.PRODUCT_ID를 조회하도록 구현했다.

그리고 더 좋은 방법을 구글링해서 찾았다

SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID, PRODUCT_ID DESC

HAVING
https://www.w3schools.com/mysql/mysql_having.asp

SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition
ORDER BY column_name(s);

3월에 태어난 여성 회원 목록

SELECT 
    MEMBER_ID, 
    MEMBER_NAME,
    GENDER,
    DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') AS DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE 
	DATE_FORMAT(DATE_OF_BIRTH, '%c') = 3 
	AND GENDER = 'W' 
    AND TLNO <> 'NULL'
ORDER BY MEMBER_ID

FROM - MEMBER_PROFILE 테이블에서
WHERE - 생일이 3월인 여성 회원의
SELECT - ID, 이름, 성별, 생년월일을 조회
WHERE - 이때 전화번호가 NULL인 경우는 출력대상에서 제외
👉 이렇게도 작성할 수 있다:

WHERE NOT TLNO IS NULL

ORDER BY - 결과는 회원ID를 기준으로 오름차순 정렬

profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글