[Lv3] 프로그래머스 MySQL 문제모음
오랜기간 보호한 동물(1)
나의 풀이
ANIMAL_INS
와 ANIMAL_OUTS
를 LEFT JOIN
시켜 NULL값을 가진 행만 찾아낸다.
SELECT A.NAME, A.DATETIME
FROM ANIMAL_INS A
LEFT JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE B.ANIMAL_ID IS NULL
ORDER BY A.DATETIME
LIMIT 3
;
오랜기간 보호한 동물(2)
나의 풀이
가장 보호기간이 길다는 것은 나간날짜-들어온날짜가 가장 크다는 것을 의미한다.
SELECT INS.ANIMAL_ID, INS.NAME
FROM ANIMAL_INS INS
JOIN ANIMAL_OUTS OUTS
ON INS.ANIMAL_ID = OUTS.ANIMAL_ID
ORDER BY (OUTS.DATETIME-INS.DATETIME) DESC
LIMIT 2
;
보호소에서 중성화한 동물
나의 풀이
SELECT A.ANIMAL_ID, A.ANIMAL_TYPE, A.NAME
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE A.SEX_UPON_INTAKE LIKE 'Intact%' AND (B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE 'Neutered%')
ORDER BY A.ANIMAL_ID;
다른 분의 풀이
WHERE 조건을 A와 B의 중성화 데이터가 다른 것으로 주어, 중성화된 동물 데이터를 찾아내었다. 두 테이블의 값이 다르다는 것은, 들어올때는 중성화가 되어있지 않았지만 나갈때에는 중성화가 되었다는 것을 의미한다. (이미 중성화가 된 채로 들어왔다면 나갈때에도 중성화가 되어있으므로 변하지 않음)
SELECT A.ANIMAL_ID, A.ANIMAL_TYPE, A.NAME
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE A.SEX_UPON_INTAKE != B.SEX_UPON_OUTCOME
ORDER BY A.ANIMAL_ID;
있었는데요 없었습니다
나의 풀이
보호 시작일(ANIMAL_INS.DATETIME)보다 입양일(ANIMAL_OUTS.DATETIME)이 더 빠른(더 오래된) 동물의 데이터를 조회해야한다.
어떤 날짜를 크기비교하면, 1970년 1월 1일부터 해당 날짜까지의 차를 밀리세컨드로 구한 값을 비교한다. 따라서 ANIMAL_INS.DATETIME>ANIMAL_OUTS.DATETIME
은 ANIMAL_INS.DATETIME
이 더 최근 날짜이므로, getTime
을 했을때 더 값이 크다는 것을 의미한다.
SELECT A.ANIMAL_ID, A.NAME
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE A.DATETIME>B.DATETIME
ORDER BY A.DATETIME
;
없어진 기록 찾기
- Left Join, Right Join
- https://programmers.co.kr/learn/courses/30/lessons/59042
나의 풀이
Left Join과 Right Join은 기능이 동일하므로, 테이블 작성 순서만 변경해주면 된다.
A LEFT JOIN B === B RIGHT JOIN A
//Left Join
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS
LEFT JOIN ANIMAL_INS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID IS NULL
ORDER BY OUTS.ANIMAL_ID;
//Right Join
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_INS INS
RIGHT JOIN ANIMAL_OUTS OUTS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID IS NULL
ORDER BY OUTS.ANIMAL_ID;
헤비 유저가 소유한 장소
다른 분의 풀이 (1)
- 2회이상 조회된 HOST_ID 목록을 서브 쿼리 테이블로 만든다.
- WHERE문에서 IN을 사용하여 서브쿼리 테이블에 존재하는 HOST_ID를 찾아 이에 해당하는 행만 조회한다.
SELECT *
FROM PLACES
WHERE HOST_ID IN (
SELECT HOST_ID
FROM PLACES
GROUP BY HOST_ID
HAVING COUNT(HOST_ID) > 1
)
ORDER BY ID
;
다른 분의 풀이 (2)
- EXISTS는 괄호 안의 서브쿼리는 값이 있다면 true를 리턴하고, 없다면 false를 리턴한다.
- IN은 데이터 셋을 생성하고, 매번 데이터를 확인해야하기 때문에 성능이 떨어지는 반면, EXISTS는 해당값이 존재하는지가 true, false로 바로 확인할 수 있으므로 IN보다 성능이 좋다.
- IN 보다는 EXISTS를 쓰는 것이 적절하다.
SELECT * FROM PLACES P1
WHERE EXISTS (
SELECT 1 FROM PLACES P2
WHERE P1.HOST_ID = P2.HOST_ID
GROUP BY HOST_ID
HAVING COUNT(ID) > 1
)
ORDER BY ID
;
EXISTS와 IN 비교
-
EXISTS
- EXISTS 뒤의 괄호 안에는 서브쿼리만 들어갈 수 있다.
- 처리순서: 메인쿼리 -> 서브쿼리 (순서대로)
서브쿼리에서 메인쿼리의 정보를 가져올 수 있으므로 서브에서 메인의 정보를 가져와 조건을 설정할 수 있다. - 서브쿼리에 대한 결과가 존재하는지만 확인한다.
- NULL 값에 대해 TRUE를 리턴한다.
-
IN
- IN 뒤에 특정 값이나 서브쿼리가 들어갈 수 있다.
- 처리순서: 서브쿼리 -> 메인쿼리 (서브먼저)
따라서 서브쿼리에서 메인쿼리의 정보를 가져올 수 없다. - NULL 값에 대해 FALSE를 리턴한다.
WHERE name IN (null, 'hello')
인 경우를 풀어쓰면 다음과 같다.WHERE name = null OR name = 'hello'
null값은IS NULL
로 비교되어야하는데 등호로 비교되고 있으므로 false가 나오게 되어name='hello'
인 것들로만 필터링된다. NOT IN의 경우도 마찬가지이다.WHERE name NOT IN (null, 'hello')
를 풀어쓰면WHERE name != null AND name !='hello'
이다. null값은IS NOT NULL
로 비교되어야하므로 false를 반환하여 empty row를 반환한다.
Author And Source
이 문제에 관하여([Lv3] 프로그래머스 MySQL 문제모음), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kaitlin_k/Lv3-프로그래머스-MySQL-문제모음저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)