https://programmers.co.kr/learn/courses/30/lessons/59411
입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 보호 기간이 긴 순으로 조회하는 SQL 문
ANIMAL_INS -- 보호소에 들어온 동물
ANIMAL_OUTS -- 보호소에서 나간 ( = 입양 간 ) 동물
따라서 ANIMAL_OUTS 에 있는 동물들은 ANIMAL_INS 에 무조건 있다 ( 데이터가 정상적으로 들어갔을 경우 )
또한 찾고자 하는 데이터는 ANIMAL_OUTS 에 있으므로
[INNER] JOIN 을 하는 것이 적절해 보인다 ( OUTER JOIN 도 가능하지만 )
( 주석으로 쓴 부분은 대체 가능한 문장 )
MySQL
# FROM 절 콤마 + WHERE 절 조건 + ORDER BY 날짜 산술 연산
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS, ANIMAL_INS INS
WHERE OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY INS.DATETIME - OUTS.DATETIME [ASC]
-- ORDER BY DATEDIFF( OUTS.DATETIME, INS.DATETIME ) DESC
-- ORDER BY DATEDIFF( INS.DATETIME, OUTS.DATETIME ) [ASC]
LIMIT 2;
# FROM 절 [INNER] JOIN + USING/ON/WHERE 절
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS [INNER] JOIN ANIMAL_INS INS
USING ( ANIMAL_ID ) # 원래 USING 절에 사용된 칼럼은 조인되면서 하나의 칼럼으로 처리되므로 ALIAS나 테이블 이름과 같은 접두사를 붙일 수 없음 (SELECT 절 등에서)
-- ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
-- WHERE OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY INS.DATETIME - OUTS.DATETIME [ASC]
-- ORDER BY DATEDIFF( OUTS.DATETIME, INS.DATETIME ) DESC
-- ORDER BY DATEDIFF( INS.DATETIME, OUTS.DATETIME ) [ASC]
LIMIT 2;
# FROM 절 LEFT/RIGHT [OUTER] JOIN + USING/ON 절
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS LEFT [OUTER] JOIN ANIMAL_INS INS
-- FROM ANIMAL_OUTS OUTS RIGHT [OUTER] JOIN ANIMAL_INS INS
USING ( ANIMAL_ID )
-- ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY IFNULL( INS.DATETIME - OUTS.DATETIME, 0 )
-- ORDER BY DATEDIFF( OUTS.DATETIME, INS.DATETIME ) DESC
-- ORDER BY IFNULL( DATEDIFF( INS.DATETIME, OUTS.DATETIME ), 0 )
LIMIT 2;
Oracle DB
# 콤마 + WHERE
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS, ANIMAL_INS INS
WHERE OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY INS.DATETIME - OUTS.DATETIME
FETCH FIRST 2 ROWS ONLY;
-- FETCH NEXT 2 ROWS ONLY; # 원래는 마지막 문장에 주석 들어가면 오류
# [INNER] JOIN + ON
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS [INNER] JOIN ANIMAL_INS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY INS.DATETIME - OUTS.DATETIME
FETCH FIRST 2 ROWS ONLY;
# [INNER] JOIN + USING
( USING 절에 사용된 칼럼은 조인되면서 하나의 칼럼으로 처리되므로 ALIAS나 테이블 이름과 같은 접두사를 붙일 수 없음
-> SELECT 절에서 'ANIMAL_ID' 칼럼 앞에 테이블 이름 뺌 )
SELECT ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS JOIN ANIMAL_INS INS
USING ( ANIMAL_ID )
ORDER BY OUTS.DATETIME - INS.DATETIME DESC
-- ORDER BY INS.DATETIME - OUTS.DATETIME
FETCH FIRST 2 ROWS ONLY;
# LEFT/RIGHT [OUTER] JOIN + ON
( 위의 경우처럼 USING 절 사용하고 SELECT 절에서 해당 칼럼 앞에 테이블명을 빼도 됨 )
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS LEFT JOIN ANIMAL_INS INS
-- FROM ANIMAL_OUTS RIGHT JOIN ANIMAL_INS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY INS.DATETIME - OUTS.DATETIME
-- ORDER BY NVL( OUTS.DATETIME - INS.DATETIME, 0 ) DESC
FETCH FIRST 2 ROWS ONLY;
# LEFT [OUTER] JOIN + ON + WHERE
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS LEFT [OUTER] JOIN ANIMAL_INS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID IS NOT NULL
ORDER BY INS.DATETIME - OUTS.DATETIME
-- ORDER BY OUTS.DATETIME - INS.DATETIME DESC
FETCH FIRST 2 ROWS ONLY;
# RIGHT [OUTER] JOIN + ON + WHERE
SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS RIGHT [OUTER] JOIN ANIMAL_INS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE OUTS.ANIMAL_ID IS NOT NULL
ORDER BY INS.DATETIME - OUTS.DATETIME
-- ORDER BY OUTS.DATETIME - INS.DATETIME DESC
FETCH FIRST 2 ROWS ONLY;
'코딩 문제 풀기 ( Algorithm problem solving ) > 프로그래머스 ( Programmers )' 카테고리의 다른 글
[프로그래머스(Programmers)][SQL] GROUP BY (Lv2) 동명 동물 수 찾기 (0) | 2022.01.07 |
---|---|
[프로그래머스(Programmers)][SQL] GROUP BY (Lv2) 고양이와 개는 몇 마리 있을까 (0) | 2022.01.07 |
[프로그래머스(Programmers)][SQL] String, Date (Lv2) DATETIME에서 DATE로 형 변환 (0) | 2022.01.07 |
[프로그래머스(Programmers)][SQL] String, Date (Lv2) 중성화 여부 파악하기 (0) | 2022.01.07 |
[프로그래머스(Programmers)][SQL] String, Date (Lv2) 이름에 el이 들어가는 동물 찾기 (0) | 2022.01.07 |