[프로그래머스] SQL 고득점 kit 풀이
어제 진행한 모 기업 코딩테스트에서 SQL 문제를 풀지 못한 충격에 바로 공부에 들어갔다. 틀릴만 했던 것이 맨날 JPA 같은 추상화 된 기술을 쓰면서 SQL
을 잘 다룬다고 착각했고 따로 SQL
공부를 잘 하지 않았다.. 반성 ..
아주 쉬운 문제만 빼고 모든 풀이를 기록하려 한다.
정답쿼리? 를 가져온 것이 아니고 프로그래머스 채점 기준이기 때문에 비효율적인 쿼리가 있을 수 있다.
✅ 상위 N개 레코드
날짜(datetime)을 기준으로 상위 N개 레코드를 select 하는 문제이다.
날짜 기준 내림차순 정렬 후 limit
를 이용해서 N개 레코드를 가져온다.
SELECT name
from animal_ins
order by datetime asc
limit 1;
✅ 중복 제거하기
동물의 이름(name)을 기준으로 중복을 제거한 row 수를 조회하는 문제이다.
중복제거는 distinct
를 row 수는 count
를 사용한다.
select count(distinct name) as 'count'
from animal_ins;
✅ 동명 동물 수 찾기
2번 이상 사용된 동물의 이름(name)을 조회하는 문제이다.
이름 별로 카운팅 후 카운팅 된 결과가 2 이상인 행을 출력한다.
SELECT name, count(name) as 'count'
from animal_ins
group by name
having count(name) > 1
order by name;
집계된 결과에 조건을 걸어야 하므로 where
가 아닌 having
을 사용한다.
✅ 입양 시각 구하기 (1)
datetime
타입의 필드에서 시간 범위 안에 있는 건 수를 조회하는 문제이다.
datetime
에서 시간에 대한 정보만 뽑아낼 수 있는 HOUR
함수를 사용한다.
시간으로 그룹핑을 수행하고 그 건수를 집계하는 방식으로 풀이한다.
SELECT HOUR(datetime), count(HOUR(datetime)) as 'count'
from animal_outs
where HOUR(datetime) between 9 and 19
group by HOUR(datetime)
order by HOUR(datetime);
✅ 입양 시각 구하기 (2)
sql
공부를 게을리 한 나에게 가장 어려웠던 문제이다.
입양 시각 구하기 (1)
와 거의 동일한 문제인데 테이블에 없는 시각까지 조회해줘야 하기 때문에 그룹핑을 사용할 수 없었다.
테이블에 없는 시각이 있기 때문에 시각에 대한 정보는 SET
을 사용해서 시각을 위한 변수를 선언하고 매 row마다 1씩 증가되도록 했다.
SET은 mysql에서 변수를 사용할 수 있는 키워드이다.
SET @변수이름 = 초기값;
SET
을 사용할 때를 제외하고 변수에 값을 바꾸려 할 때는 =
이 아니고 :=
를 사용해야 한다.
SET
을 제외한 모든 곳에서 =
는 동등성 검사로 사용되기 때문이다.
SET @HOUR = -1;
SELECT (@HOUR := @HOUR +1) as 'HOUR',
(
SELECT count(HOUR(datetime))
FROM animal_outs
WHERE HOUR(datetime) = @HOUR
) as 'COUNT'
FROM animal_outs
WHERE @HOUR < 23;
매 row마다 증가되는 @HOUR
와 같은 시각(HOUR(datetime)
)을 갖는 row를 카운팅하는 방식이다.
매 row마다 @HOUR
가 증가되므로 종료조건이 필요하다.
WHERE @HOUR < 23
✅ NULL 처리하기
칼럼의 값이 null
인 경우 다른 값으로 대체할 수 있는가를 묻는 문제이다.
ifnull(값, '대체값')
을 사용한다.
SELECT animal_type, ifnull(name, 'No name'), sex_upon_intake
from animal_ins
order by animal_id
name
칼럼이 null
인 경우 No name
을 대체값으로 사용한다.
✅ 없어진 기록 찾기
이 문제는 관계를 맺은 두 테이블이 있을 때 한 쪽 테이블에만 있는 데이터를 찾을 수 있는가를 묻는다.
보호소에 들어온 동물에 대한 테이블 animal_ins
입양 간 동물에 대한 테이블 animal_outs
가 있을 때 입양은 보냈지만 보호소에 들어온 기록이 없는 동물을 찾아야 한다.
조인칼럼은 animal_id
이다.
데이터가 확실히 있는 쪽을 기준으로 left join
을 수행한다.
문제에서는 animal_outs
가 될 것이다.
데이터가 확실히 있는 쪽을 기준으로 left join
하게 되면 기준이 되는 테이블의 모든 데이터는 모두 들고오고 join
되는 테이블에 데이터가 없는 경우 null
로 채워서 들고 온다.
left join animal_ins ai on ao.animal_id = ai.animal_id
join
되는 테이블에서 null
인 것만 들고오면 조인 기준 테이블에만 있는 데이터를 찾게 된다.
where ai.animal_id is null;
답
select ao.animal_id, ao.name
from animal_outs ao
left join animal_ins ai on ao.animal_id = ai.animal_id
where ai.animal_id is null;
✅ 오랜 기간 보호한 동물(1)
없어진 기록 찾기 문제와 거의 동일한 문제이다.
관계를 맺은 테이블에서 한 쪽에만 있는 데이터를 찾아야 한다.
한 쪽에만 => left join
& is null
SELECT ai.name, ai.datetime
from animal_ins ai
left join animal_outs ao on ai.animal_id = ao.animal_id
where ao.animal_id is null
order by ai.datetime
limit 3;
보호소에 들어왔지마 아직 입양가지 않는 동물 중 보호소에 들어온 날짜가 오래된 3마리 동물을 조회한다.
데이터가 확실히 있는 쪽을 기준으로 하고 (from
절에 두고) left join
을 수행한다. 데이터가 없을 수 있는 join
되는 테이블을 기준으로 null
체크를 수행한다.
✅ 보호소에서 중성화한 동물
SELECT ai.animal_id, ai.animal_type, ai.name
from animal_ins ai
join animal_outs ao on ai.animal_id = ao.animal_id
where ai.sex_upon_intake like 'Intact%' and (ao.sex_upon_outcome like 'Spayed%' or ao.sex_upon_outcome like 'Neutered%')
order by ai.animal_id;
기본적인 inner join
과 like
를 쓸 줄 아는 지 물어보는 문제이다.
✅ 중성화 여부 파악하기
특정 칼럼을 기준으로 조건을 걸고 조건에 부합하는 경우 특정 문자를 부합하지 않는 경우 특정 문자를 출력해야 하는 문제이다.
select
절에서 if
문을 사용해서 풀이한다.
select if(조건, 'O', 'X');
ex)
select if(answer=True, 'O', 'X');
SELECT animal_id, name,
if(sex_upon_intake like 'Neutered%' or sex_upon_intake like 'Spayed%',
'O', 'X') as '중성화'
from animal_ins
order by animal_id;
✅ 오랜 기간 보호한 동물(2)
SELECT ai.animal_id, ai.name
from animal_ins ai
join animal_outs ao on ai.animal_id = ao.animal_id
order by ao.datetime - ai.datetime desc
limit 2;
Author And Source
이 문제에 관하여([프로그래머스] SQL 고득점 kit 풀이), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dhk22/프로그래머스-SQL-고득점-kit-풀이저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)