[TIL] #5 프로그래머스 GROUP BY

kiteB·2021년 8월 14일
0

TIL-SQL

목록 보기
4/7
post-thumbnail

📌 GROUP BY


이번 SQL 고득점 Kit 유형은 GROPU BY!

"나랑 이름이 같은 사람은 몇 명일까요? 데이터를 묶고 평균값을 계산해보세요."

이번에도 GROUP BY에 대해 알아보고 문제를 풀어보자!

GROUP BY

MySQL에서 유형별로 개수를 가져오고 싶을 때, 단순히 COUNT 함수로 데이터를 조회하면 전체 개수만 가져온다!

이럴 때 GROUP BY를 사용한다.

GROUP BY

  • 선택된 레코드의 집합을 필드의 값이나 표현식에 의해 그룹화한 결과 집합을 반환한다.
  • 즉, GROUP BY절은 하나의 그룹을 하나의 레코드로 반환하므로, 결과 집합의 크기를 줄여주는 역할을 한다.

기본 형태

SELECT [필드명][그룹함수(필드명)]
FROM [테이블명]
GROUP BY [필드명]

: 테이블명 테이블의 필드명을 기준으로 집계 함수(COUNT(필드명)을 실행한다.

예제

SELECT Gender, COUNT(Gender) as count
FROM Student
GROUP BY Gender

: Student의 수를 Gender로 구분하여 가져오기.

출력 예시

Gendercount
M10
F10

HAVING

특정 컬럼을 그룹화한 결과에 조건을 거는 키워드
+) WHERE는 그룹화 하기 전에 조건을 거는 것이고, HAVING은 그룹화한 후에 조건을 건다!

예제

SELECT Age, COUNT(Age) as count
FROM Student
GROUP BY Age
HAVING COUNT(Age) >= 10

: Student의 수를 Age로 구분하여 가져올 때, 해당 Age 사람 수가 10명 이상인 데이터만 가져오기

출력 예시

Agecount
1015
2010
4011

이제 문제를 풀어보자!

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


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

문제 정리

  1. 테이블 정보
    ANIMAL_INS : 동물 보호소에 들어온 동물의 정보를 담은 테이블

  2. 필드 정보
    ANIMAL_ID: 동물의 아이디
    ANIMAL_TYPE: 생물 종
    DATETIME: 보호 시작일
    INTAKE_CONDITION: 보호 시작 시 상태
    NAME: 이름
    SEX_UPON_INTAKE: 성별 및 중성화 여부

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

💡 POINT

  • 고양이와 개가 몇 마리인지 구해야 한다.
  • 고양이를 개보다 먼저 나오게 해야 한다.

내 코드

SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE

SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS count : ANIMAL_TYPE, count (COUNT(ANIMAL_TYPE))를 출력.
FROM ANIMAL_INS: ANIMAL_INS 테이블 선택
GROUP BY ANIMAL_TYPE: ANIMAL_TYPE 별로 그룹을 만든다.
ORDER BY ANIMAL_TYPE: CatDog보다 먼저 나와야하므로 ANIMAL_TYPE을 오름차순으로 정렬한다.

다른 사람 코드

🔗 link

SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS COUNT
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY
CASE ANIMAL_TYPE
	WHEN 'Cat' THEN 1
	WHEN 'Dog' THEN 2
	ELSE 3
END

📌 ORDER BY절에 CASE WHEM 사용하기 (조건 정렬)

  • 기본 형태
CASE [필드명] 
   WHEN [필드값1] THEN 1
   WHEN [필드값2] THEN 2
   ELSE 3
END
  • 예제
CASE Fruit
   WHEN 'Apple' THEN 1
   WHEN 'Grape' THEN 2
   ELSE 3
END

: Apple, Grape 순으로 데이터가 출력된다.


✔ 동명 동물 수 찾기


🔗 LEVEL2. 동명 동물 수 찾기

문제 정리

  1. 테이블 정보
    ANIMAL_INS : 동물 보호소에 들어온 동물의 정보를 담은 테이블

  2. 필드 정보
    ANIMAL_ID: 동물의 아이디
    ANIMAL_TYPE: 생물 종
    DATETIME: 보호 시작일
    INTAKE_CONDITION: 보호 시작 시 상태
    NAME: 이름
    SEX_UPON_INTAKE: 성별 및 중성화 여부

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

💡 POINT

  • NAMECOUNT를 구하고, 이 횟수가 2 이상인 값만 출력한다.
  • NAME을 기준으로 오름차순으로 정렬!

내 코드

SELECT NAME, COUNT(NAME) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME

SELECT NAME, COUNT(NAME) AS COUNT : NAME, COUNT (COUNT(NAME)) 출력
FROM ANIMAL_INS: ANIMAL_INS 테이블 선택
GROUP BY NAME: NAME 별로 그룹을 만든다.
HAVING COUNT(NAME) >= 2: NAME이 2번 이상 등장한 것만 조회
ORDER BY NAME: NAME을 기준으로 오름차순 정렬

✔ 입양 시각 구하기(1)


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

문제 정리

  1. 테이블 정보
    ANIMAL_OUTS : 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블

  2. 필드 정보
    ANIMAL_ID: 동물의 아이디
    ANIMAL_TYPE: 생물 종
    DATETIME: 입양일
    NAME: 이름
    SEX_UPON_INTAKE: 성별 및 중성화 여부

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

💡 POINT

  • 입양일(DATETIME) 중에서 시간이 09:00~19:59인 값 조회
  • 위에서 구한 값을 시간대별로 나눠서 COUNT 값을 구한다.
  • 결과는 시간대를 기준으로 오름차순으로 정렬하기

내 코드

SELECT HOUR(DATETIME) AS HOUR, COUNT(DATETIME) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN 9 AND 19
GROUP BY HOUR(DATETIME)
ORDER BY HOUR(DATETIME)

SELECT HOUR(DATETIME) AS HOUR, COUNT(DATETIME) AS COUNT : DATETIME에서 HOUR만 추출한 값과 , COUNT (COUNT(DATETIME)) 출력
FROM ANIMAL_OUTS: ANIMAL_OUTS 테이블 선택
WHERE HOUR(DATETIME) BETWEEN 9 AND 19: HOUR(DATETIME)이 9 이상 19인 값만 추출한다. (시간이 9~19인 값만 추출)
GROUP BY HOUR(DATETIME): HOUR(DATETIME) 별로 그룹을 만든다.
ORDER BY HOUR(DATETIME): HOUR(DATETIME)을 기준으로 오름차순 정렬

📌 HOUR(DATETIME)

  • HOUR(DATETIME)를 하면 시간만 추출해낼 수 있다.
  • 이외에도 YEAR, MONTH, DAY, MINUTE, SECOND가 있다.

✔ 입양 시각 구하기(2)


🔗 LEVEL4. 입양 시각 구하기(2)

문제 정리

  1. 테이블 정보
    ANIMAL_OUTS : 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블

  2. 필드 정보
    ANIMAL_ID: 동물의 아이디
    ANIMAL_TYPE: 생물 종
    DATETIME: 입양일
    NAME: 이름
    SEX_UPON_INTAKE: 성별 및 중성화 여부

  3. 문제
    ✔ 보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 한다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성하라. 이때 결과는 시간대 순으로 정렬해야 한다.

💡 POINT

  • 입양일(DATETIME) 중에서 시간만 추출
  • 위에서 구한 값을 COUNT해서 출력하기
  • 결과는 시간대를 기준으로 오름차순으로 정렬하기

내 코드

특정 시간대에 입양된 기록이 없을 때 값을 0으로 채워야하는데 어떻게 하는지 몰라서 못 풀었다😢 갑자기 어려워져서 당황했는데 레벨 4였다.. 어쩐지...

다른 사람 코드

🔗 link

문제 접근 방법

💡 POINT

  • DATETIME의 모든 시간대마다 데이터가 있는 것이 아니라서 따로 처리하지 않으면 NULL인 시간대는 출력이 안된다!
    SET을 활용해서 새로운 칼럼을 만들어준 다음, 값을 채워준다!

📌 SET
: SET은 어떤 변수에 특정 값을 할당할 때 사용하는 명령어이다.


1. 사용자 정의 변수 선언 및 초기화

SET @변수이름 = 대입값; 혹은 SET @변수이름 := 대입값;
SELECT @변수이름:=대입값;

: SET 이외의 명령문에서는 =가 비교연산자로 취급되기 때문에 SELECT로 변수를 선언하고 대입할 때는 :=을 사용한다.


2. 사용자 정의 변수 사용법

SET @start = 15, @finish = 20;
또는
SELECT @start := 15, @finish = 20;
SELECT * FROM EMPLOYEE WHERE ID BETWEEN @start AND @finish;
  • start 변수를 15로, finis 변수를 20으로 초기화한다.
  • EMPLOYEE 테이블에서 ID 값이 start(15) ~ finish(20) 사이인 레코드만 가져오라는 뜻


    3. 참고사항
  • 저장하는 값에 의해 자료형이 정해지며, Integer, Decimal, Float, Binary, String만 취급할 수 있다.
  • 변수를 초기화하지 않은 경우, 값은 NULL, 자료형은 String 타입이다.

Code

SET @HOUR = -1;
SELECT @HOUR := @HOUR + 1 AS HOUR,
      (SELECT COUNT(*)
       FROM ANIMAL_OUTS
       WHERE @HOUR = HOUR(DATETIME)) AS COUNT
FROM ANIMAL_OUTS
WHERE @HOUR < 23

하아 어렵다,, SQL 공부 이틀 째인 나에게는 너무 어려워서 눈물이 날 것 같지만 이해해보려고 해보자,,

단계별로 이해해보자😢

SET @HOUR = -1;

: HOUR라는 변수를 -1로 초기화한다.

SELECT @HOUR := @HOUR + 1 AS HOUR

: HOUR 변수가 1씩 증가하도록 만들어준다.

SELECT COUNT(*)
   FROM ANIMAL_OUTS
   WHERE @HOUR = HOUR(DATETIME)) AS COUNT

: 서브 쿼리에서는 현재 HOUR 변수값과 ANIMAL_OUTSHOUR(DATETIME)이 같은 DATETIMECOUNT 해준다.

+) 서브 쿼리 : 하나의 SQL 문에 포함되어 있는 또 다른 SQL

WHERE @HOUR < 23

: 위의 쿼리문의 결과를 @HOUR < 23까지만 실행해서 결론적으로 HOUR를 0 ~ 23까지 출력해준다.

📌 참고 자료


https://extbrain.tistory.com/56
https://velog.io/@kimju0913/sql-Union%EA%B3%BC-Union-All
https://coding-factory.tistory.com/88
https://three-pleasure.tistory.com/256

profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글