코딩공부

내일배움캠프 47일차

정해인3 2023. 7. 20. 20:51

오늘은 팀 프로젝트 4일차다. 

어제의 쿼리문에 내가 태그된 글을 조회하는 기능을 추가하여 1차 완성을 하였다.

하지만 같은 게시글은 1번만 조회하고 싶은데 조건이 동시에 충족되면 같은 게시글을 2회 이상 출력하는 문제가 아직 남아있었다. 

group by p.id를 사용하고 싶지만 lp.created_at을 이용해 정렬하고 있기 때문에 둘 사이에 충돌이 있는지 사용할 수가 없었다. 

수많은 삽질 끝에 max(lp.created_at)을 사용하면 group by도 사용할 수 있고 가장 최근에 마음찍힌 글 하나만 남길 수 있다는 것을 깨달았다. 

다음이 완성된 sql문이다. 

select p.id, p.created_at, p.modified_at, p.content, p.image_url, p.views, u.user_id
from post p
    left join likes_post lp on p.id = lp.post_id
    left join users u on p.user_id = u.user_id
    left join follows f on u.user_id = f.following_user_id
    left join follows f2 on lp.user_id = f2.following_user_id
    left join tag_user_in_post tuip on p.id = tuip.post_id
    where (lp.created_at in (select min(lp.created_at)
        from post p left join likes_post lp
        on p.id = lp.post_id
        where (p.user_id = ?1)))
    or ((p.user_id = ?1) and (lp.created_at is null))
    or (lp.user_id = ?1)
    or (lp.created_at in (select min(lp.created_at)
        from  post p
        left join follows f on p.user_id = f.following_user_id
        left join likes_post lp on p.id = lp.post_id
        where (f.follower_user_id = ?1)))
    or((f.follower_user_id = ?1)and (lp.created_at is null))
    or((f2.follower_user_id = ?1) and (lp.user_id = f2.following_user_id))
    or(tuip.user_id = ?1)
    group by p.id, p.created_at
    order by (if(max(lp.created_at) > p.created_at, max(lp.created_at), p.created_at)) desc;

 

하지만 내가 작성한 글과 내가 팔로우한 사람이 작성한 글이 마음이 찍힐 때마다(나나 팔로하지 않은 사람이 마음을 찍더라도!) 상단으로 갱신되는 문제가 해결되지 않았다는 것을 알았다 

where문 내부의 서브쿼리로는 이 문제가 충분히 해결되지 않아 삭제하고 또 수많은 삽질 끝에 order by문에 서브쿼리를 작성하는 아래 방식으로 해결했다. 

select p.id, p.created_at, p.modified_at, p.content, p.image_url, p.views, u.user_id, max(lp.created_at)
from post p
    left join likes_post lp on p.id = lp.post_id
    left join users u on p.user_id = u.user_id
    left join follows f on u.user_id = f.following_user_id
    left join follows f2 on lp.user_id = f2.following_user_id
    left join tag_user_in_post tuip on p.id = tuip.post_id
    where p.user_id = ?1
    or f.follower_user_id = ?1
    or (lp.user_id = ?1)
    or((f2.follower_user_id = ?1) and (lp.user_id = f2.following_user_id))
    or(tuip.user_id = ?1)
    group by p.id, p.created_at
    order by if(p.created_at in (select p.created_at from post p
                                 left join users u on p.user_id = u.user_id
                                 left join follows f on u.user_id = f.following_user_id
                                 where  p.user_id = ?1
                                 or f.follower_user_id = ?1),
                p.created_at, (if(max(lp.created_at) > p.created_at, max(lp.created_at), p.created_at))) desc;