다른 테이블과의 조인이 필요할 때
그 중에서도 조건부로 조인을 해야할 것 같을 때가 있다.
그럴땐 join 보다는
select의 projection에 원하는 조건에 따라 각기 다른 서브쿼리를 실행하도록 하는게 좋다고 한다.
SELECT
index,
type,
item_list,
start_date,
end_date,
updated_date,
created_date,
-- type ; 0: all, 1: only target user, 2: except target user
(if(MAIL.type = 0, true,
if(MAIL.type = 1,
(SELECT true FROM MAIL_TARGET WHERE MAIL.type = 1 AND mail_index = MAIL.index AND user_id = @user_id),
NOT exists (SELECT 1 FROM MAIL_TARGET WHERE MAIL.type = 2 AND mail_index = MAIL.index AND user_id = @user_id))
)
) is_target
FROM
MAIL
WHERE
index > (SELECT IFNULL(MAX(index), 0) FROM USER_MAIL_INDEX WHERE user_id = @user_id)
AND ( (@user_grant < 1 AND now() BETWEEN start_date AND end_date
AND @user_join_date <= start_date)
OR (@user_grant >= 1 AND now() <= end_date))
아쭈 어지러워보이는 쿼리지만,
인덱스만 잘 걸려있으면 무난하게 동작한다.
(아직까지는)