Backend/DB

group by count 0 적용 count ifnull 안됨

개발하는루루 2022. 11. 7. 14:28

# Mysql 에서 join 후 group by 시에 null값 혹은 0 값은 나오지 않을때

# group by count 0 적용 count ifnull 안됨

select count(e.ESSAY_ID) as totalCount from score s, essay e where s.ESSAY_ID = e.ESSAY_ID and e.user_id = :user_id group by e.user_id;

 

user_id로 group by한 다음에 count를 해주는 쿼리이다.

 

이 때, user_id로 그룹핑 해주었을 때 row값이 하나도 없으면 상식적으로는 0을 뱉을거라 생각했지만

그렇지 않았다.

 

그렇다고 count(ifnull(e.ESSAY_ID, 0))를 한다고 0이 나오지도 않았다.

 

score <->   essay 조인 테이블은 scored_essay를 찾는 테이블인데 애초에 이 테이블에 검색하려는 user_id가  하나도 채점된 에세이가 없으면, score <->   essay 조인 테이블에 user_id로 검색되는 게 없을 것이니 group by를 하려고 해도 아무것도 없는 게 당연하다.

 

조금 찾아보니 count 집계 함수는 null을 포함하여 세지 않는다. 

이것을 역으로 이용하면 조회하려는 목록을 바꿔서, user와 <-> scored_essay를 join해서 null을 포함하여 카운팅하면 된다. 

 

 

select count(*) as totalCount from essay_user eu left join (select e.ESSAY_ID, e.USER_ID  from score s, essay e where s.ESSAY_ID = e.ESSAY_ID) as se on eu.USER_ID = se.user_id where se.USER_ID = :user_id

처음에 어떻게든 group by만을 활용하여 쿼리를 짜려했지만, group by의 key값으로 조회할  수 없는 테이블이 생긴다면

left join을 활용하면 충분히 원하는 값을 가져올 수 있다.

 

어쨋든 돌고돌아 어렵게 접근했지만 매우 간단하게 쿼리를 쓰는 방법도 있다. 

select count(*) from score, essay where essay.USER_ID = :user_id and essay.ESSAY_ID = score.ESSAY_ID;

 

 

매우..매우..깔끔하다.

처음에 group by에 집착하여 left join까지 오게 됐지만 

group by를 쓸 때 고려해야 하는 점을 잘 생각해봐야겠다고 느꼈고 언제 left join을 하면 되는지도 배우게 됐다.

 

그리고.. 저 바로 위의 간단한 코드를 보며 든 생각이.. 저정도면 쿼리 메쏘드로 쓸 수 있지 않을까?

정답은 Yes다.

 

바로 위 코드를 JPQL 쿼리 메쏘드로 옮기면 아래와 같다.

 

long countByEssay_UserId(String user_id);

Essay entity는 실제로 Score Entity와 1:1 join column으로 명시되어 있으므로 아래와 같이 사용하면 네이티브 쿼리 없이 쓸 수 있다.

countBy Join되어있는 엔티티 _ 컬럼명

주의할 점은, count의 output의 타입은 long 타입을 반환한다는 점만 알면 된다.