[프로그래머스(Programmers)][SQL] String, Date (Lv3) 오랜 기간 보호한 동물 (2)

728x90

 

https://programmers.co.kr/learn/courses/30/lessons/59411

 

코딩테스트 연습 - 오랜 기간 보호한 동물(2)

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

 

입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리아이디이름보호 기간이 긴 순으로 조회하는 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;

 

 

반응형