1번이 가장 좋은 풀이이며, 밑으로 내려갈수록 가독성이 떨어지는 코드입니다.
IN절, DISTINCT 사용 / GROUP BY 사용x
SELECT DISTINCT CAR_ID,
IF(CAR_ID IN (SELECT DISTINCT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE), '대여중', '대여 가능') AS AVAILABILTIY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
ORDER BY CAR_ID DESC
LEFT JOIN 사용
SELECT DISTINCT H.CAR_ID, IF(R.CAR_ID IS NULL, '대여 가능', '대여중') AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H
LEFT JOIN (SELECT DISTINCT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE) R ON H.CAR_ID=R.CAR_ID
ORDER BY CAR_ID DESC
IF + SUM 사용
SELECT CAR_ID, IF(SUM(IF('2022-10-16' BETWEEN START_DATE AND END_DATE, 1, 0))=0, '대여 가능', '대여중') AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY GROUP BY CAR_ID ORDER BY CAR_ID DESC
IF + MAX 사용
SELECT CAR_ID, MAX(IF(START_DATE<='2022-10-16' AND '2022-10-16'<=END_DATE, '대여중', '대여 가능')) AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY GROUP BY CAR_ID ORDER BY CAR_ID DESC
3번 풀이 해설
안쪽의 IF절 'IF('2022-10-16' BETWEEN STARTDATE AND ENDDATE, 1, 0)' 을 통해
대여중일 경우 1, 대여 중이 아닐 경우 0으로 표시된다.
이것들을 SUM 함수로 모두 더했을 때, 값이 0이라면(=모든 데이터가 대여 중이 아닐 경우, 0+0+0+0 ..) 대여 가능 상태라고 판단할 수 있다.
따라서 다시 한번 IF절로 감싸서, SUM절이 0일 경우 '대여 가능'으로 표시하고,
대여중인 자동차가 있어 SUM절이 0이 아닐 경우에는 '대여중'으로 표시하여 해결함.
4번 풀이 해설
IF절을 통해 대여 중인 경우 '대여중', 대여 중이 아닌 경우 '대여 가능' 이라고 출력될 것이다.
이때 문제에서 요구하는 '대여 가능'이 되려면, 해당 CAR_ID의 모든 값이 '대여 가능'이여야 '대여 가능' 이라고 판단할 수 있다. 만약 IF절에서 나온 값에 '대여중'과 '대여 가능'이 함께 있다면 이 자동차는 '대여중'이라고 출력되어야 한다.
(다시 말해, '대여 가능' 상태라면 모든 데이터가 '대여 가능'일 경우에만 가능하다.)
SELECT IF('대여중'>'대여 가능', 1, 0);
로 검색해보면 1이 나온다. 즉, '대여중 > 대여 가능'이다.
따라서 IF문에서 나온 값을 MAX() 함수로 처리하면,
모든 데이터가 '대여중'이면 -> '대여중'이,
모든 데이터가 '대여 가능'이면 -> '대여 가능'이,
'대여중'과 '대여 가능'이 함께 존재하면 -> '대여중' 이
출력될 것이다.
위와 같이 IF와 MAX 함수를 같이 사용하여 문제에서 원하는 최종 답을 출력할 수 있다.
굿!
감사합니당
궁금한 게 있는데 1번 방식으로 하게 되면 모든 ROW에 대해서 IN절의 SELECT문이 실행되고,
2번 방식으로 하게 되면 JOIN을 붙인 다음에 각 ROW에 대해서 IF문이 실행되어서
2번 방식이 더 효율적일 것 같아서 2번으로 풀었는데, 혹시 왜 1번 방식이 더 좋은 방식일까요??
제가 성능쪽은 아예 모르겠어서 여쭤봅니다!