인기 페이지 구현(좋아요 수 많은 이미지 차례대로 출력)
인기페이지를 구현하려고 한다.
인기페이지란, 좋아요 수가 많은 이미지를 차례대로 출력해 화면에 보여주는 페이지이다.
상황 설명을 하겠다.
현재 사이트에 가입한 user 는 총 3명이다. (user = 1,2,3 존재)
지금 로그인한 user =1 이다.
user 1은,
user 2 의 이미지(A)에 좋아요를 눌렀고,
user 3의 이미지(B)에도 좋아요를 눌렀다.
그런데 user2 역시 user 3의 이미지(B) 에 좋아요를 눌러서,
결과적으로
좋아요 수는
user 2의이미지(A) : 1
user 3의 이미지(B) : 2
가 된다.
따라서 user1 의 인기페이지에는
B ,A 순으로 화면에 나타나게 된다.
이를 직접 쿼리로 구현해야 한다.
먼저 image db는
이와 같은 칼럼으로 이루어져 있고,
likes db는 아래와 같은 칼럼으로 이루어져 있다.
즉 우리는 최종적으로 likes db의 좋아요 수를 계산하여, 이 조건이 적용된
image db 의 값들을 가져올 것이다.
그럼 쿼리를 만들어 보겠다.
# 쿼리 1
SELECT * FROM image;
일단 image db를 확인해본다.
그러면 이렇게 이미지 2개가 나온다.
첫번째 이미지(id=1)는 위에서 설명한 user 2 의 이미지 (A)이고,
두번째 이미지(id=2) 는 위에서 설명한 user 3의 이미지(B)이다.
# 쿼리 2
SELECT * FROM likes;
likes db를 확인해본다.
첫번째와 세번째 id를 보면, imageId =2 즉 user 3의 이미지(B)를
userId = 1,2 가 좋아요 하고 있음을 알 수 있다.
두번째 id를 보면, imageId=1 즉, user 2의 이미지(A)를 user 1가 좋아요 하고 있음을 알 수 있다.
# 쿼리 3
SELECT imageId, COUNT(imageId) likeCount FROM likes GROUP BY imageId;
COUNT(imageId) 한 결과를 likeCount 칼럼에 나타낸다.
COUNT(imageId)란, imageId 개수를 세어서 즉, 위의 쿼리 결과에서, imageId =1, 2 각각의 개수를 센다는 것.
즉,
imageId=1 일 때 userId 는 1로, 결과값이 1개 있으므로 좋아요 수( likeCount)는 1이다.
imageId =2 일 때 userId가 1,2 로 결과값이 2개 있으므로 likeCount는 2이다.
이것을 GROUP BY imageId
즉, imageId 순서대로 정렬해서 나타내면 쿼리 결과가 나온다.
이렇게 결과가 나온다.
# 쿼리 4
SELECT *
FROM image i INNER JOIN (SELECT imageId, COUNT(imageId) likeCount FROM likes GROUP BY imageId) c
ON i.id = c.imageId;
여기서 INNER JOIN 을 볼 수 있다.
INNER JOIN 괄호 안에 있는 쿼리는
쿼리 3이다.
이 쿼리문은,
1) SELECT * : 즉 모든 값을 가져와라,
2) FROM image i : image db 데이터 값과 (image db 별칭 : i )
3) INNER JOIN (SELECT imageId, COUNT(imageId) likeCount FROM likes GROUP BY imageId) c
: 쿼리 3에서 나온 결과값 중 (결과값의 별칭 : c)
4) ON i.id = c.imageId;
: image db 에서 imageId 값과
쿼리 3의 결과에서 imageId 값이 같은 것들의 값을 가져오라는 뜻
즉, 쿼리 1에서 image db를 보면,
이렇게 imageId = 1,2 가 있다.
그러면 쿼리 3의 결과값 중
여기서 imageId =1 ,2 를 만족하는 값(여기서는 다른 이미지가 없으므로 모든 값들을 말함)을 가져오면
이렇게, imageId 가 같은
image db의 결과값과 쿼리 3의 결과값이 이어붙여져서 같이 나오게 된다.
INNER JOIN
참고 자료 : https://gent.tistory.com/376
# 쿼리 5
SELECT *
FROM image i INNER JOIN (SELECT imageId, COUNT(imageId) likeCount FROM likes GROUP BY imageId) c
ON i.id = c.imageId
ORDER BY likeCount DESC;
likeCount값에 대해서 내림차순해서 화면에 이미지를 나타낼 것이므로,
즉 좋아요 수가 많은 이미지가 위에 나오도록
ORDER BY 를 이용해서 내림차순 정렬한다.
결과값:
그런데, 우리는 그냥 image db 의 데이터만 있으면 되지, 쿼리 3의 결과값은 필요 없으므로,
이를 지워내도록한다.
(쿼리 3은 image db의 데이터들을 정렬해서 나타내는데에만 쓰이지,
화면에 이미지를 출력할 때 쓰이지 않으므로 )
# 쿼리 6
SELECT i.*
FROM image i INNER JOIN (SELECT imageId, COUNT(imageId) likeCount FROM likes GROUP BY imageId) c
ON i.id = c.imageId
ORDER BY likeCount DESC;
결과:
이렇게 쿼리 3의 결과, 즉 imageId, likeCount 가 사라졌다.
--------------
이 쿼리를 Repository.java에서 nativeQuery를 이용해서 사용하면 된다.
참고 자료 : 이지업 강의 사이트 "스프링부트 SNS 프로젝트 - 포토그램 만들기"