[SQL] 프로그래머스 문제 풀이 모음

peace w·2023년 10월 22일
0

ORACLE

목록 보기
1/1

프로그래머스에서 SQL 문제도 풀어 볼 수 있다. Java에 비하면 문제 수가 많지 않아 문제 카테고리 별로 정리했다. 동일한 카테고리 안의 문제는 난이도 순으로 정렬했다.

SELECT

LV.1

  1. 모든 레코드 조회하기

동물 보호소에 들어온 모든 동물의 정보를 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

  SELECT *
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID;
  1. 역순 정렬하기

동물 보호소에 들어온 모든 동물의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 ANIMAL_ID 역순으로 보여주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

SELECT NAME, DATETIME
  FROM ANIMAL_INS
 ORDER BY ANIMAL_ID DESC;
  1. 아픈 동물 찾기

동물 보호소에 들어온 동물 중 아픈 동물1의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.

SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
 WHERE INTAKE_CONDITION = 'Sick'
  1. 어린 동물 찾기

동물 보호소에 들어온 동물 중 젊은 동물1의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.

SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
 WHERE INTAKE_CONDITION != 'Aged'
 ORDER BY ANIMAL_ID ;
  1. 동물의 아이디와 이름

동물 보호소에 들어온 모든 동물의 아이디와 이름을 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
 ORDER BY ANIMAL_ID;
  1. 여러 기준으로 정렬하기

동물 보호소에 들어온 모든 동물의 아이디와 이름, 보호 시작일을 이름 순으로 조회하는 SQL문을 작성해주세요. 단, 이름이 같은 동물 중에서는 보호를 나중에 시작한 동물을 먼저 보여줘야 합니다.

SELECT ANIMAL_ID, NAME, DATETIME
  FROM ANIMAL_INS
 ORDER BY NAME ASC, DATETIME DESC;
  1. 상위 n개 레코드

동물 보호소에 가장 먼저 들어온 동물의 이름을 조회하는 SQL 문을 작성해주세요.

최소값을 구하는 경우 min 을 사용하면 된다. WHERE절에 MIN함수를 사용하여 최소값인 조건만 출력한다.

SELECT NAME
  FROM ANIMAL_INS
 WHERE DATETIME
    IN (SELECT MIN(DATETIME)
          FROM ANIMAL_INS
       );

데이터 중에서 최상단 n개를 출력해달라고 하면 ROWNUM이나 FETCH FIRST ROWS를 사용할 수도 있다.

SELECT NAME
  FROM (SELECT DATETIME, NAME FROM ANIMAL_INS ORDER BY DATETIME ASC)
 WHERE ROWNUM = 1;

FROM 절에서 서브쿼리로 DATETIME을 추출한 다음에 WHERE 절에서 ROWNUM=1을 사용해서 최상단 값을 출력한다.

SELECT NAME
  FROM ANIMAL_INS
ORDER BY DATETIME
FETCH FIRST 1 ROWS ONLY;

SELECT 절을 한 번만 이용하고 싶으면 FETCH 구문을 이용하면 된다.

  1. 인기있는 아이스크림

상반기에 판매된 아이스크림의 맛을 총주문량을 기준으로 내림차순 정렬하고 총주문량이 같다면 출하 번호를 기준으로 오름차순 정렬하여 조회하는 SQL 문을 작성해주세요.

SELECT FLAVOR
  FROM FIRST_HALF
 ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID ASC;
  1. 조건에 맞는 회원수 구하기

USER_INFO 테이블에서 2021년에 가입한 회원 중 나이가 20세 이상 29세 이하인 회원이 몇 명인지 출력하는 SQL문을 작성해주세요.

SELECT COUNT(USER_ID) AS USERS
  FROM USER_INFO
 WHERE JOINED >= TO_DATE(20210101, 'YYYY-MM-DD') 
   AND JOINED <= TO_DATE(20211231, 'YYYY-MM-DD')
   AND AGE >= 20 
   AND AGE <= 29;

TO_DATE함수로 문자형이나 컬럼을 원하는 형식의 날짜 포맷으로 바꿀 수 있다.

SELECT TO_DATE('0000-00-00', 'YYYY-MM-DD')

TO_CHAR함수를 사용해서 날짜를 다양한 형태의 문자로 바꿀 수도 있다. 아래 코드에서 필요한 만큼만 입력하면 원하는 시간 단위만큼 자를 수 있다.

TO_CHAR(데이터, 'YYYY-MM-DD HH24-MM-SS')

TO_CHAR를 이용한 코드는 아래와 같다.

SELECT COUNT(USER_ID) AS USERS
  FROM USER_INFO
 WHERE TO_CHAR(JOINED, 'YYYY') = '2021'
   AND AGE >= 20 
   AND AGE <= 29;
  1. 12세 이하인 여자 환자 목록 출력하기

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

SELECT PT_NAME
      ,PT_NO
      ,GEND_CD
      ,AGE
      ,CASE 
        WHEN TLNO IS NULL THEN 'NONE'
        ELSE TLNO
       END AS TLNO
  FROM PATIENT
 WHERE AGE <= 12 AND GEND_CD = 'W'
 ORDER BY AGE DESC, PT_NAME ASC;

CASE WHEN 을 사용하여 전화번호가 없는 경우를 'NONE'으로 출력하였지만
전화번호가 없는 경우는 데이터가 NULL이므로 NVL()함수를 사용하는 것이 더 편리하다.

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

NVL(칼럼, NULL일 경우 대체할 값) 이라고 작성해주면 된다.

  1. 평균 일일 대여 요금 구하기

CAR_RENTAL_COMPANY_CAR 테이블에서 자동차 종류가 'SUV'인 자동차들의 평균 일일 대여 요금을 출력하는 SQL문을 작성해주세요. 이때 평균 일일 대여 요금은 소수 첫 번째 자리에서 반올림하고, 컬럼명은 AVERAGE_FEE 로 지정해주세요.

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

AVG()로 평균값을 구하고 ROUND()로 반올림하면 된다.

소수 올림 내림 하기

SELECT FLOOR(10.1)FROM DUAL; // 내림,10
SELECT CEIL(10.1)FROM DUAL; // 올림,11 

SELECT ROUND(10.777, 2); // 입력한 자릿수까지 반올림, 10.78
SELECT TRUNC(10.777, 2); // 입력한 자릿수까지 내림, 10.77
 
  1. 조건에 맞는 도서 리스트 출력하기

BOOK 테이블에서 2021년에 출판된 '인문' 카테고리에 속하는 도서 리스트를 찾아서 도서 ID(BOOK_ID), 출판일 (PUBLISHED_DATE)을 출력하는 SQL문을 작성해주세요.
결과는 출판일을 기준으로 오름차순 정렬해주세요.

SELECT BOOK_ID, TO_CHAR(PUBLISHED_DATE, 'YYYY-MM-DD') AS PUBLISHED_DATE
  FROM BOOK
 WHERE CATEGORY = '인문'
   AND PUBLISHED_DATE
   BETWEEN TO_DATE('2021-01-01', 'YYYY-MM-DD')
   AND TO_DATE('2021-12-31', 'YYYY-MM-DD')
 ORDER BY PUBLISHED_DATE;

원하는 시간 범위만큼 뽑고 싶으면 BETWEEN AND 를 이용할 수 있다.

BETWEEN TO_DATE('2021-01-01', 'YYYY-MM-DD')
    AND TO_DATE('2021-12-31', 'YYYY-MM-DD')

EXTRACT 를 사용하여 추출하는 것도 가능하다.

EXTRACT(YEAR FROM PUBLISHED_DATE) = '2021'
-- year, month, day, hour, minute, second 가능 

EXTRACT를 사용하면 아래처럼 작성하면 된다.

SELECT BOOK_ID, TO_CHAR(PUBLISHED_DATE, 'YYYY-MM-DD') AS PUBLISHED_DATE
  FROM BOOK
 WHERE CATEGORY = '인문'
  AND EXTRACT(YEAR FROM PUBLISHED_DATE) = '2021'  
 ORDER BY PUBLISHED_DATE;
  1. 과일로 만든 아이스크림 고르기

상반기 아이스크림 총주문량이 3,000보다 높으면서 아이스크림의 주 성분이 과일인 아이스크림의 맛을 총주문량이 큰 순서대로 조회하는 SQL 문을 작성해주세요.

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

ICECREAM_INFO 와 FIRST_HALF 두 테이블을 JOIN하여 함께 사용해야한다. JOIN할 때는 어느 테이블의 칼럼인지 분간할 수 있도록 테이블명.컬럼명 으로 사용하자.

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

USED_GOODS_BOARDUSED_GOODS_REPLY 테이블에서 2022년 10월에 작성된 게시글 제목, 게시글 ID, 댓글 ID, 댓글 작성자 ID, 댓글 내용, 댓글 작성일을 조회하는 SQL문을 작성해주세요. 결과는 댓글 작성일을 기준으로 오름차순 정렬해주시고, 댓글 작성일이 같다면 게시글 제목을 기준으로 오름차순 정렬해주세요.

SELECT ub.TITLE, ub.BOARD_ID, ur.REPLY_ID, ur.WRITER_ID, ur.CONTENTS
     , TO_CHAR(ur.CREATED_DATE, 'YYYY-MM-DD') AS CREATED_DATE
  FROM USED_GOODS_BOARD ub
 INNER JOIN USED_GOODS_REPLY ur
    ON ub.BOARD_ID = ur.BOARD_ID
 WHERE TO_CHAR(ub.CREATED_DATE, 'YYYY-MM') = '2022-10'
 ORDER BY ur.CREATED_DATE ASC, ub.TITLE ASC;
  1. 흉부외과 또는 일반외과 의사 목록 출력하기

DOCTOR 테이블에서 진료과가 흉부외과(CS)이거나 일반외과(GS)인 의사의 이름, 의사ID, 진료과, 고용일자를 조회하는 SQL문을 작성해주세요. 이때 결과는 고용일자를 기준으로 내림차순 정렬하고, 고용일자가 같다면 이름을 기준으로 오름차순 정렬해주세요.

SELECT DR_NAME, DR_ID, MCDP_CD, TO_CHAR(HIRE_YMD, 'YYYY-MM-DD') AS HIRE_YMD
  FROM DOCTOR
 WHERE MCDP_CD = 'CS' OR MCDP_CD = 'GS'
 ORDER BY HIRE_YMD DESC, DR_NAME ASC;
  1. 강원도에 위치한 생산공장 목록 출력하기

FOOD_FACTORY 테이블에서 강원도에 위치한 식품공장의 공장 ID, 공장 이름, 주소를 조회하는 SQL문을 작성해주세요. 이때 결과는 공장 ID를 기준으로 오름차순 정렬해주세요.

SELECT FACTORY_ID , FACTORY_NAME, ADDRESS
  FROM FOOD_FACTORY
 WHERE ADDRESS LIKE '%강원도%'
 ORDER BY FACTORY_ID ASC;

LV.2

  1. 3월에 태어난 여성 회원 목록 출력하기

MEMBER_PROFILE 테이블에서 생일이 3월인 여성 회원의 ID, 이름, 성별, 생년월일을 조회하는 SQL문을 작성해주세요. 이때 전화번호가 NULL인 경우는 출력대상에서 제외시켜 주시고, 결과는 회원ID를 기준으로 오름차순 정렬해주세요.

SELECT MEMBER_ID, MEMBER_NAME, GENDER, TO_CHAR(DATE_OF_BIRTH, 'YYYY-MM-DD') AS DATE_OF_BIRTH
  FROM MEMBER_PROFILE
 WHERE EXTRACT(MONTH FROM DATE_OF_BIRTH) = 3
   AND TLNO IS NOT NULL
   AND GENDER = 'W' 
 ORDER BY MEMBER_ID;
  1. 재구매가 일어난 상품과 회원 리스트 구하기

ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.

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

GROUP BY를 통해서 묶어야 COUNT 가 가능하다. GROUP BY는 각종 집계함수와 함께 쓰이며 그룹화된 정보를 준다.
쉽게 얘기하자면 00별 정보처럼 데이터를 그룹으로 나누는 것. 즉 그룹별로 집계된 정보를 출력하거나 비교할 때 사용해야 한다.

LV.4

  1. 서울에 위치한 식당 목록 출력하기

REST_INFOREST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.

SELECT a.REST_ID, a.REST_NAME, a.FOOD_TYPE, a.FAVORITES, a.ADDRESS, ROUND(AVG(b.REVIEW_SCORE),2) AS SCORE
  FROM (SELECT *
          FROM REST_INFO
         WHERE ADDRESS LIKE '서울%') a
 INNER JOIN REST_REVIEW b
    ON a.REST_ID = b.REST_ID
 GROUP BY a.REST_ID, a.REST_NAME, a.FOOD_TYPE, a.FAVORITES, a.ADDRESS
 ORDER BY SCORE DESC, a.FAVORITES DESC
  • 두 테이블의 데이터가 필요하므로 INNER JOIN을 사용
  • 리뷰의 평균을 구해야하므로 GROUP BY 사용
    (JOIN 된 전체 테이블을 보면 동일한 REST_ID, REST_NAME, FOOD_TYPE, FAVORITES, ADDRESS를 가진 값들이 리뷰점수만 다르게 n개씩 들어가있음. 필요한 칼럼으로 그룹을 다 묶어줘야 함.)
  • 주소가 서울로 시작하는 조건을 만족해야하므로 LIKE '서울%'
  1. 오프라인/온라인 판매 데이터 통합하기

ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.

  • 우선 ONLINE_SALE 테이블과 OFFLINE_SALE 테이블을의 데이터를 합쳐서 위아래로 정렬해야하므로 UNION을 써야한다.
    • JOIN은 데이터를 옆으로 추가해주지만 UNION은 데이터를 위아래로 추가해준다.
SELECT * FROM TEMP
UNION
SELECT * FROM TEMP2

이렇게 사용하면 되고, 각 테이블의 컬럼 갯수가 같아야만 가능하다.
FROM 뒤에 ( ~~ UNION ~~) 이런 식으로 쓸 수도 있음.

  • 그리고 OFFLINE_SALE 테이블에는 USER_ID 값이 없다. 문제에서 USER_ID의 값을 NULL로 넣으라고 명시해뒀으니 그렇게 하자.
NULL AS USER_ID

이렇게 하면 모두 값이 NULL인 USER_ID 칼럼을 새로 넣을 수 있따.

SELECT TO_CHAR(A.SALES_DATE, 'YYYY-MM-DD') AS SALES_DATE, A.PRODUCT_ID, A.USER_ID, A.SALES_AMOUNT
  FROM (SELECT USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE
          FROM ONLINE_SALE
         WHERE TO_CHAR(SALES_DATE, 'YYYY-MM') = '2022-03'
        
         UNION
        
       (SELECT NULL AS USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE
          FROM OFFLINE_SALE
         WHERE TO_CHAR(SALES_DATE, 'MM') = '03')) A
 ORDER BY SALES_DATE, A.PRODUCT_ID, A.USER_ID;
  • TO_CHAR()로 필요한 년월일만 빼온다.
  • ORDER BY SALES_DATE, A.PRODUCT_ID, A.USER_ID; 라고 작성했지만 ORDER BY 1,2,3; 이라고 써도 된다. (칼럼순서대로)

SUM, MAX, MIN

LV.1

  1. 가장 비싼 상품 구하기

PRODUCT 테이블에서 판매 중인 상품 중 가장 높은 판매가를 출력하는 SQL문을 작성해주세요. 이때 컬럼명은 MAX_PRICE로 지정해주세요.

SELECT MAX(PRICE) AS MAX_PRICE
  FROM PRODUCT;
  1. 최댓값 구하기

가장 최근에 들어온 동물은 언제 들어왔는지 조회하는 SQL 문을 작성해주세요.

SELECT MAX(DATETIME) AS 시간
  FROM ANIMAL_INS;

LV.2

  1. 가격이 제일 비싼 식품의 정보 출력하기

FOOD_PRODUCT 테이블에서 가격이 제일 비싼 식품의 식품 ID, 식품 이름, 식품 코드, 식품분류, 식품 가격을 조회하는 SQL문을 작성해주세요.

SELECT *
  FROM FOOD_PRODUCT
 WHERE PRICE = (SELECT MAX(PRICE)
                FROM FOOD_PRODUCT);
SELECT *
  FROM FOOD_PRODUCT
 ORDER BY PRICE DESC
 FETCH FIRST 1 ROWS ONLY;
  1. 최솟값 구하기

동물 보호소에 가장 먼저 들어온 동물은 언제 들어왔는지 조회하는 SQL 문을 작성해주세요.

SELECT MIN(DATETIME) AS 시간
  FROM ANIMAL_INS
  1. 동물 수 구하기

동물 보호소에 동물이 몇 마리 들어왔는지 조회하는 SQL 문을 작성해주세요.

SELECT COUNT(*) AS COUNT
  FROM ANIMAL_INS
  1. 중복 제거하기

동물 보호소에 들어온 동물의 이름은 몇 개인지 조회하는 SQL 문을 작성해주세요. 이때 이름이 NULL인 경우는 집계하지 않으며 중복되는 이름은 하나로 칩니다.

SELECT COUNT(DISTINCT NAME) AS COUNT
  FROM ANIMAL_INS
 WHERE NOT NAME IS NULL;

GROUP BY

LV.2.

  1. 고양이와 개는 몇 마리 있을까

동물 보호소에 들어온 동물 중 고양이와 개가 각각 몇 마리인지 조회하는 SQL문을 작성해주세요. 이때 고양이를 개보다 먼저 조회해주세요.

SELECT ANIMAL_TYPE, COUNT(*) AS COUNT
  FROM ANIMAL_INS
 GROUP BY ANIMAL_TYPE
 ORDER BY ANIMAL_TYPE;
  1. 동명 동물 수 찾기

동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요. 이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회해주세요.

SELECT NAME, COUNT(NAME) AS COUNT
  FROM ANIMAL_INS 
 GROUP BY NAME
 HAVING COUNT(NAME) > 1
 ORDER BY NAME;

두 번 이상 쓰인 이름을 출력해야하므로 HAVING 절로 GROUP에 조건을 달아준다.

  1. 입양 시각 구하기(1)

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

필요한 건 시간과 시간을 count한 칼럼이다.
그런데 시간을 어떻게 숫자로 변환할까? 방법은 아래와 같다.

방법1. TO_NUMBER를 사용해서 시간의 숫자를 가져오기

 SELECT TO_NUMBER(TO_CHAR(DATETIME, 'HH24')) AS HOUR
      ,COUNT(*) AS COUNT
  FROM ANIMAL_OUTS
 WHERE TO_CHAR(DATETIME, 'HH24:MI') BETWEEN '09:00' AND '19:59' 
 GROUP BY TO_CHAR(DATETIME, 'HH24')
 ORDER BY HOUR;

방법2. EXTRACT 로 추출하기

 SELECT HOUR, COUNT(HOUR) AS COUNT
   FROM (SELECT EXTRACT(HOUR FROM CAST(DATETIME AS TIMESTAMP)) AS HOUR
         FROM ANIMAL_OUTS
        )
  GROUP BY HOUR
 HAVING HOUR BETWEEN 9 AND 19
  ORDER BY HOUR;
  1. 성분으로 구분한 아이스크림 총 주문량

상반기 동안 각 아이스크림 성분 타입과 성분 타입에 대한 아이스크림의 총주문량을 총주문량이 작은 순서대로 조회하는 SQL 문을 작성해주세요. 이때 총주문량을 나타내는 컬럼명은 TOTAL_ORDER로 지정해주세요.

총주문량이므로 합계를 구해야한다. 주문정보 테이블과 성분 타입 테이블을 JOIN 한 후 성분 타입 칼럼을 그룹으로 묶으면 된다.

SELECT i.INGREDIENT_TYPE, SUM(f.TOTAL_ORDER) AS TOTAL_ORDER
  FROM FIRST_HALF f
 INNER JOIN ICECREAM_INFO i
    ON f.FLAVOR = i.FLAVOR
 GROUP BY i.INGREDIENT_TYPE
 ORDER BY TOTAL_ORDER;
  1. 진료과별 총 예약 횟수 출력하기

APPOINTMENT 테이블에서 2022년 5월에 예약한 환자 수를 진료과코드 별로 조회하는 SQL문을 작성해주세요. 이때, 컬럼명은 '진료과 코드', '5월예약건수'로 지정해주시고 결과는 진료과별 예약한 환자 수를 기준으로 오름차순 정렬하고, 예약한 환자 수가 같다면 진료과 코드를 기준으로 오름차순 정렬해주세요.

SELECT MCDP_CD AS "진료과코드"
      ,COUNT(MCDP_CD) AS "5월예약건수"
  FROM APPOINTMENT
 WHERE TO_CHAR(APNT_YMD, 'YYYY-MM') = '2022-05' 
 GROUP BY MCDP_CD
 ORDER BY "5월예약건수", "진료과코드";
  1. 가격대 별 상품 개수 구하기

PRODUCT 테이블에서 만원 단위의 가격대 별로 상품 개수를 출력하는 SQL 문을 작성해주세요. 이때 컬럼명은 각각 컬럼명은 PRICE_GROUP, PRODUCTS로 지정해주시고 가격대 정보는 각 구간의 최소금액(10,000원 이상 ~ 20,000 미만인 구간인 경우 10,000)으로 표시해주세요. 결과는 가격대를 기준으로 오름차순 정렬해주세요.

PRICE_GROUP 을 0, 10000, 20000, 30000 ... 이런 식으로 나누어야 하는데 방법이 3가지가 있다.
(예시에는 0이 있지만 실제 테이블을 출력하면 10000원 미만의 값은 없다.)

  1. 수로 취급, FLOOR 사용
SELECT FLOOR(PRICE / 10000) * 10000 AS PRICE_GROUP
       , COUNT(*) AS PRODUCTS
  FROM PRODUCT
 GROUP BY FLOOR(PRICE / 10000) * 10000
 ORDER BY FLOOR(PRICE / 10000) * 10000;

FLOOR() 함수는 소수점 첫째 자리에서 버림하는 함수로, 주어진 숫자와 가장 근접한 작은 정수를 출력한다.

  1. 문자열로 취급해서 자르기
SELECT CONCAT(SUBSTR(PRICE,1,1), '0000') AS PRICE_GROUP
       , COUNT(*) AS PRODUCTS
  FROM PRODUCT
 GROUP BY CONCAT(SUBSTR(PRICE,1,1), '0000')
 ORDER BY CONCAT(SUBSTR(PRICE,1,1), '0000');

SUBSTR() 함수를 이용했다.
SUBSTR(문자열, 시작위치, 길이)로 사용할 수 있다. SQL에서 인덱스는 0이 아니라 1부터 시작한다. 0이라고 적으면 1로 자동 계산한다.
SUBSTR을 통해서 잘라낸 앞자리와 '0000'을 CONCAT()함수를 써서 합친다.

  1. TRUNC()
SELECT TRUNC(PRICE, -4) AS PRICE_GROUP, COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY TRUNC(PRICE, -4)
ORDER BY PRICE_GROUP ASC

TRUNC로 날짜, 시간, 요일, 숫자를 절사할 수 있다. 숫자의 경우 양수를 넣으면 소수점을 자르는데 음수를 넣으면 0의 자리부터 자를 수 있다.

IS NULL

LV.1

  1. 경기도에 위치한 식품창고 목록 출력하기

FOOD_WAREHOUSE 테이블에서 경기도에 위치한 창고의 ID, 이름, 주소, 냉동시설 여부를 조회하는 SQL문을 작성해주세요. 이때 냉동시설 여부가 NULL인 경우, 'N'으로 출력시켜 주시고 결과는 창고 ID를 기준으로 오름차순 정렬해주세요.

 SELECT WAREHOUSE_ID, WAREHOUSE_NAME, ADDRESS, NVL(FREEZER_YN,'N') AS FREEZER_YN
   FROM FOOD_WAREHOUSE
  WHERE ADDRESS LIKE '%%경기도%%'  
  ORDER BY WAREHOUSE_ID;
  1. 이름이 없는 동물의 아이디

동물 보호소에 들어온 동물 중, 이름이 없는 채로 들어온 동물의 ID를 조회하는 SQL 문을 작성해주세요. 단, ID는 오름차순 정렬되어야 합니다.

SELECT ANIMAL_ID
  FROM ANIMAL_INS
 WHERE NAME IS NULL
 ORDER BY ANIMAL_ID;
  1. 이름이 있는 동물의 아이디

동물 보호소에 들어온 동물 중, 이름이 있는 동물의 ID를 조회하는 SQL 문을 작성해주세요. 단, ID는 오름차순 정렬되어야 합니다.

SELECT ANIMAL_ID
  FROM ANIMAL_INS
 WHERE NAME IS NOT NULL
 ORDER BY ANIMAL_ID;
  1. 나이 정보가 없는 회원 수 구하기

USER_INFO 테이블에서 나이 정보가 없는 회원이 몇 명인지 출력하는 SQL문을 작성해주세요. 이때 컬럼명은 USERS로 지정해주세요.

SELECT COUNT(*) AS USERS
  FROM USER_INFO
 WHERE AGE IS NULL;

LV.2

  1. NULL 처리하기

입양 게시판에 동물 정보를 게시하려 합니다. 동물의 생물 종, 이름, 성별 및 중성화 여부를 아이디 순으로 조회하는 SQL문을 작성해주세요. 이때 프로그래밍을 모르는 사람들은 NULL이라는 기호를 모르기 때문에, 이름이 없는 동물의 이름은 "No name"으로 표시해 주세요.

위에서 얘기한 것 처럼 CASE WHEN을 사용할 수도 있고,

SELECT ANIMAL_TYPE
     , CASE
       WHEN NAME IS NULL THEN 'No name'
       ELSE NAME
       END AS  NAME
     , SEX_UPON_INTAKE
  FROM ANIMAL_INS
 ORDER BY ANIMAL_ID;

NVL이나 COALESCE같은 NULL값을 치환하는 함수를 사용해도 된다.

SELECT 
   ANIMAL_TYPE
  ,NVL(NAME, 'No name')
  ,SEX_UPON_INTAKE
 FROM ANIMAL_INS
ORDER BY ANIMAL_ID;

COALESCENVL과 똑같이 동작하나, 여러개의 컬럼의 NULL값을 판별해야 할 경우 유용하게 사용 가능하다.

profile
더 성장하자.

0개의 댓글