[프로그래머스/SQL 고득점 Kit] SUM, MAX, MIN

2024. 9. 17. 18:53코딩 테스트(Coding Test)/프로그래머스

가장 비싼 상품 구하기

나의 답1)

SELECT MAX(PRICE) AS MAX_PRICE
FROM PRODUCT;

# PRODUCT에서
# 가장 높은 판매가 출력 -> MAX_PRICE

 

나의 답2)

SELECT PRICE AS MAX_PRICE
FROM PRODUCT
ORDER BY PRICE DESC
LIMIT 1;

# PRODUCT에서
# 가장 높은 판매가 출력 -> MAX_PRICE

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

나의 답)

SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, PRICE
FROM FOOD_PRODUCT
ORDER BY PRICE DESC
LIMIT 1;

# FODD_PRODUCT에서
# 가격이 제일 비싼 식품의
# 식품ID, 식품 이름, 식품 코드, 식품분류, 식품가격 조회

최댓값 구하기

나의 답1)

SELECT DATETIME AS '시간'
FROM ANIMAL_INS
WHERE DATETIME = (SELECT MAX(DATETIME) FROM ANIMAL_INS);

# ANIMAL_INS에서
# 가장 최근에 들어온 동물이
# 언제 들어왔는지 조회

 

나의 답2)

SELECT DATETIME AS '시간'
FROM ANIMAL_INS
ORDER BY DATETIME DESC
LIMIT 1;

# ANIMAL_INS에서
# 가장 최근에 들어온 동물이
# 언제 들어왔는지 조회

최솟값 구하기

나의 답1)

SELECT DATETIME AS '시간'
FROM ANIMAL_INS
WHERE DATETIME = (SELECT MIN(DATETIME) FROM ANIMAL_INS);

# ANIMAL_INS에서
# 가장 먼저 들어온 동물이
# 언제 들어왔는지 조회

 

나의 답2)

SELECT DATETIME AS '시간'
FROM ANIMAL_INS
ORDER BY DATETIME ASC
LIMIT 1;

# ANIMAL_INS에서
# 가장 먼저 들어온 동물이
# 언제 들어왔는지 조회

동물 수 구하기

나의 답)

SELECT COUNT(*)
FROM ANIMAL_INS;

# ANIMAL_INS에서
# 동물이 몇 마리 들어왔는지 조회

중복 제거하기

나의 답)

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

# ANIMAL_INS에서
# 동물의 이름은 몇 개인지 조회
# if) 이름 == NULL -> 집계x

조건에 맞는 아이템들의 가격의 총합 구하기

나의 답)

SELECT SUM(PRICE) AS TOTAL_PRICE
FROM ITEM_INFO
WHERE RARITY = 'LEGEND';

# ITEM_INFO에서
# 희귀도가 'LEGEND'인 아이템들의
# 가격의 총합 출력 -> 'TOTAL_PRICE'

 

* SUM()을 사용하는데 GROUP BY를 사용하면 안되는 이유

: SUM()은 그룹화가 필요한 경우에 GROUP BY와 함께 사용되지만, 이 문제에서는 특정 희귀도를 가진 아이템들의 총합을 구하는 것이 목적이다. 즉, 모든 희귀도가 'LEGEND'인 아이템들의 가격을 하나의 그룹으로 보고 합계를 내야 된다.

 

GROUP BY는 데이터를 특정 기준에 따라 그룹화할 때 사용되는데, 현재 문제에서 PRICE로 그룹화하면 가격이 동일한 아이템끼리만 그룹화가 이루어진다. 그러나 이 문제에서는 가격에 따라 그룹화할 필요가 없고 단순히 희귀도가 'LEGEND'인 아이템들의 전체 합계를 구하는 것이 목적이므로 GROUP BY를 사용할 필요가 없다.


물고기 종류 별 대어 찾기

나의 답1)

SELECT fi.ID, fni.FISH_NAME, fi.LENGTH
FROM FISH_INFO fi
JOIN FISH_NAME_INFO fni ON fi.FISH_TYPE = fni.FISH_TYPE
WHERE (fi.FISH_TYPE, fi.LENGTH) IN (
    SELECT FISH_TYPE, MAX(LENGTH)
    FROM FISH_INFO
    WHERE LENGTH IS NOT NULL
    GROUP BY FISH_TYPE
)
ORDER BY ID ASC;

# FISH_INFO, FISH_NAME_INFO에서
# 물고기 종류 별로 가장 큰 물고기의
# ID, 이름(FISH_NAME), 길이(LENGTH)
# ID ASC

 

* WHERE () IN ()

: 튜플을 사용하여 여러 열을 동시에 비교할 때 사용하는 방식이다. 간단히 말해, 여러 열의 조합이 서브쿼리의 결과와 일치하는 행을 찾는 것이다. 여기서 중요한 점은 서브쿼리에서 반환되는 결과가 튜플 형식이라는 것이다. 하나의 열이 아니라 두 개 이상의 열이 결합된 값을 조건으로 비교하는 것이다.

 

* 튜플 비교 WHERE (fi.FISH_TYPE, fi.LENGTH)
: fi.FISH_TYPE과 fi.LENGTH는 각각 물고기의 종류와 길이를 나타내는 두 개의 열이다. 이 두 열의 조합이 서브쿼리에서 반환된 결과와 일치하는지 확인하는 것이 WHERE (fi.FISH_TYPE, fi.LENGTH)의 역할이다.

 

나의 답2)

WITH MaxSizeFish AS (
    SELECT FISH_TYPE, MAX(LENGTH) AS MAX_LENGTH
    FROM FISH_INFO
    GROUP BY FISH_TYPE
)
SELECT ID, FISH_NAME, LENGTH
FROM FISH_INFO fi
JOIN MaxSizeFish msf
ON fi.FISH_TYPE = msf.FISH_TYPE AND fi.LENGTH = msf.MAX_LENGTH
JOIN FISH_NAME_INFO fni
ON fi.FISH_TYPE = fni.FISH_TYPE
ORDER BY fi.ID;

# FISH_INFO, FISH_NAME_INFO에서
# 물고기 종류 별로 가장 큰 물고기의
# ID, 이름(FISH_NAME), 길이(LENGTH)
# ID ASC

 

* MaxSizeFish: 물고기 종류별 최대 길이를 계산한 결과를 담는다.


잡은 물고기 중 가장 큰 물고기의 길이 구하기

나의 답1)

SELECT CONCAT(MAX(LENGTH), 'cm') AS MAX_LENGTH
FROM FISH_INFO;

# FISH_INFO에서
# 가장 큰 물고기의 길이를 'cm'를 붙여 출력 -> MAX_LENGTH

 

나의 답2)

SELECT CONCAT(LENGTH, 'cm') AS MAX_LENGTH
FROM FISH_INFO
ORDER BY LENGTH DESC
LIMIT 1;

# FISH_INFO에서
# 가장 큰 물고기의 길이를 'cm'를 붙여 출력 -> MAX_LENGTH

연도별 대장균 크기의 편차 구하기

나의 답1)

WITH MaxSizePerYear AS (
    SELECT YEAR(DIFFERENTIATION_DATE) AS YEAR, MAX(SIZE_OF_COLONY) AS MAX_SIZE
    FROM ECOLI_DATA
    GROUP BY YEAR
)
SELECT m.YEAR, (m.MAX_SIZE - e.SIZE_OF_COLONY) AS YEAR_DEV, e.ID
FROM ECOLI_DATA e
LEFT JOIN MaxSizePerYear m
ON YEAR(DIFFERENTIATION_DATE) = m.YEAR
ORDER BY m.YEAR ASC, YEAR_DEV ASC;
# ECOLI_DATA에서
# 분화된 연도(YEAR), 분화된 연도별 대장균 크기의 편차(YEAR_DEV), 대장균 개체의 ID(ID) 출력
# 참고) YEAR_DEV = 분화된 연도별 가장 큰 대장균의 크기 - 각 대장균의 크기
# 연도 ASC, 대장균 크기의 편차 ASC

 

나의 답2)

SELECT
  EXTRACT(YEAR FROM DIFFERENTIATION_DATE) AS YEAR,
  (MAX(SIZE_OF_COLONY) OVER (PARTITION BY EXTRACT(YEAR FROM DIFFERENTIATION_DATE)) - SIZE_OF_COLONY) AS YEAR_DEV,
  ID
FROM ECOLI_DATA
ORDER BY YEAR ASC, YEAR_DEV ASC;


# ECOLI_DATA에서
# 분화된 연도(YEAR), 분화된 연도별 대장균 크기의 편차(YEAR_DEV), 대장균 개체의 ID(ID) 출력
# 참고) YEAR_DEV = 분화된 연도별 가장 큰 대장균의 크기 - 각 대장균의 크기
# 연도 ASC, 대장균 크기의 편차 ASC

 

* EXTRACT(YEAR FROM DIFFERENTIATION_DATE) AS YEAR
: 대장균의 분화된 연도를 추출한다.

 

* (MAX(SIZE_OF_COLONY) OVER (PARTITION BY EXTRACT(YEAR FROM DIFFERENTIATION_DATE))

: 분화된 연도별 가장 큰 대장균의 크기를 구한다.

 

* (MAX(SIZE_OF_COLONY) - SIZE_OF_COLONY)

: 각 대장균의 크기 편차를 계산한다.

 

* EXTRACT(): 날짜 또는 시간 값에서 특정한 부분(예: 연도, 월, 일 등)을 추출하는 함수이다.

 

* OVER (PARTITION BY EXTRACT(YEAR FROM DIFFERENTIATION_DATE))

: PARTITION BY는 데이터를 특정 기준으로 그룹화(여기서는 연도별로)하여 각 그룹 내에서 최대값을 계산합니다.