๐ [ํ๋ก๊ทธ๋๋จธ์ค] ๊ทธ๋ฃน๋ณ ์กฐ๊ฑด์ ๋ง๋ ์๋น ๋ชฉ๋ก ์ถ๋ ฅํ๊ธฐ
ํ์คํ join์ชฝ ๋ฌธ์ ๊ฐ ์ด๋ ค์ด ๊ฒ ๊ฐ๋ค...
๋ฌธ์
MEMBER_PROFILE
์ REST_REVIEW
ํ
์ด๋ธ์์ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์์ฑํ ํ์์ ๋ฆฌ๋ทฐ๋ค์ ์กฐํํ๋ SQL๋ฌธ์ ์์ฑํด์ฃผ์ธ์. ํ์ ์ด๋ฆ, ๋ฆฌ๋ทฐ ํ
์คํธ, ๋ฆฌ๋ทฐ ์์ฑ์ผ์ด ์ถ๋ ฅ๋๋๋ก ์์ฑํด์ฃผ์๊ณ , ๊ฒฐ๊ณผ๋ ๋ฆฌ๋ทฐ ์์ฑ์ผ์ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์, ๋ฆฌ๋ทฐ ์์ฑ์ผ์ด ๊ฐ๋ค๋ฉด ๋ฆฌ๋ทฐ ํ
์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌํด์ฃผ์ธ์.
ํ์ด
1. ์ฒ์ ์ฝ๋
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN (SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) COUNTS) R_CNT
ON(R.MEMBER_ID = R_CNT.MEMBER_ID) JOIN MEMBER_PROFILE M
ON (R_CNT.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
2. CTE ์ฌ์ฉ (1. ์ฒ์ ์ฝ๋๋ฅผ ์ ๋ฆฌ)
- CTE๋ฅผ ์ฌ์ฉํ๋ ํจ์ฌ ๊ฐ๋ ์ฑ์ด ๋ ์ข์์ง ๊ฒ ๊ฐ๋ค.
WITH MOST_REVIEWS AS (
SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) CNT_R
)
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN MOST_REVIEWS
ON(R.MEMBER_ID = MOST_REVIEWS.MEMBER_ID)
JOIN MEMBER_PROFILE M
ON (MOST_REVIEWS.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
์์ธ ํ์ด
- ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์์ฑํ ํ์๋ค์ ์๊ธฐ ์ํด RANK() OVER๋ฅผ ์ฌ์ฉํ๋ค. ๋จผ์ ,
MEMBER_ID
๋ฅผ ๊ธฐ์ค์ผ๋ก GROUP BYํ๊ณ COUNT() ํจ์๋ฅผ ํตํดREST_ID
์ ๊ฐ์๋ฅผ ์ธ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ๊ทธ ์๋ธ์ฟผ๋ฆฌ์ CNT๋ฅผ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ์ฌ RANK๋ฅผ ๋งค๊ฒผ๋ค. - ์๋ธ์ฟผ๋ฆฌ์์ GROUP BY๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ์๋น ํ๋์ ๋ฆฌ๋ทฐ๋ง ๋ํ๋๋ค.
- ๊ฐ์ฅ ๋ง์ด ์์ฑํ ๋ฆฌ๋ทฐ ์๋ 3๊ฐ์ด๋ฉฐ 3๋ช ์ ํ์์ด ๊ฐ์ฅ ๋ง์ ๋ฆฌ๋ทฐ๋ฅผ ์์ฑํ๋ค.
WITH MOST_REVIEWS AS (
SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) CNT_R
)

REST_REVIEW
ํ ์ด๋ธ์ ์กฐ์ธํ ์ด์ ๋ ๊ฐ์ฅ ๋ฆฌ๋ทฐ๋ฅผ ๋ง์ด ๋จ๊ธด ํ์์ ๋ฆฌ๋ทฐ๊น์ง ์ถ๋ ฅํด์ผ ๋๋๋ฐMOST_REVIEWS
์์๋ ๊ฐ์ฅ ๋ง์ด ๋ฆฌ๋ทฐ๋ฅผ ๋จ๊ธด ํ์๋ง ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.MEMBER_NAME
์ ์ถ๋ ฅํ๊ธฐ ์ํดMEMBER_PROFILE
ํ ์ด๋ธ๋ ์กฐ์ธํด์ค๋ค.- RANK๊ฐ 1์ธ ์กฐ๊ฑด์ ์ค๋ค.
REVIEW_DATE
์REVIEW_TEXT
๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN MOST_REVIEWS
ON(R.MEMBER_ID = MOST_REVIEWS.MEMBER_ID)
JOIN MEMBER_PROFILE M
ON (MOST_REVIEWS.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
์ฌ๋ด
- ๋๋ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ๋จ๊ธด ํ์๋ค์ ๋ชจ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ถ๋ ฅ๋ ์ ์๊ฒ ์ฟผ๋ฆฌ๋ฅผ ์งฐ์๋ค. (3๋ช ์ด ๊ณต๋ 1์๋ก ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ผ๋ค๋ฉด ๊ทธ ํ์๋ค์ด ์ผ๋ ๋ชจ๋ ๋ฆฌ๋ทฐ๊ฐ ์ถ๋ ฅ๋๊ฒ ํ์๋ค)
- ๋ค๋ฅธ ๋ถ๋ค์ ํ์ด๋ฅผ ๋ณด๋ ๊ฐ์ฅ ๋ง์ ๋ฆฌ๋ทฐ๋ฅผ ์ผ๋ ํ์ 1๋ช
์ ๋ํ ๋ชจ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ถ๋ ฅํด๋ ์ ๋ต ์ฒ๋ฆฌ๊ฐ ๋๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ๊ทธ๋์
limit 1
์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ ๊ฒ ๊ฐ๋ค.
ํ๊ณ
- ์ฒ์ ์ฝ๋๋ฅผ ์์ฑํ ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค๋ณด๋ ๋ฒ์๊ฐ ํค๊ฐ๋ ค์ ์ค๋ฅ๊ฐ ๋ง์ด ๋ฌ์๋ค. (ex. ๊ดํธ๋ alias ๋ฑ) ๋ ๊ฐ๋ ์ฑ์ด ๋ง์ด ๋จ์ด์ ธ์ ๊ฒํ ํ ๋ ๋ถํธํ๋ค.
- ์ฒ์ ์ฝ๋๋ฅผ CTE๋ก ์์ฑํ๋ ๊ฐ๋ ์ฑ์ด ๋์์ ธ์ ๊ฒํ ํ๊ธฐ ํธํด์ก๋ค.
- ์์ง๊น์ง RANK() OVER๋ฅผ ๋ค๋ฃจ๋ ๊ฒ์ด ๋ฏธ์ํ์ฌ ์ฐ์ต์ด ํ์ํ๋ค.
- ํ๋ก๊ทธ๋๋จธ์ค ๊ฒ์ํ์์ ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค CTE๊ฐ ๋ฉด์ ์์ ์ค๋ช ํ๊ธฐ ์ฝ๊ณ ์ฝ๋ ๋ฆฌ๋ทฐ์๋ ์ข์ ์ ์๋ฅผ ๋ฐ์ ์ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ฝ๋๋ฅผ ๋ณด๋๋ผ๋ ๊ฐ๋ ์ฑ์ด ์ข์ ํธํ ๊ฒ ๊ฐ๋ค. CTE์ ์ต์ํด์ ธ์ผ ๊ฒ ๋ค. ๐ ์ฐธ๊ณ ๋งํฌ
Ref.
1. ํ๋ก๊ทธ๋๋จธ์ค (CTE ๊ด๋ จ) / https://school.programmers.co.kr/questions/45837
2. ํ๋ก๊ทธ๋๋จธ์ค (๋ฌธ์ ์๋ ๊ด๋ จ) / https://school.programmers.co.kr/questions/41349
3. RANK() OVER์ COUNT() / https://denodo1.tistory.com/355
* ์๋ชป๋ ๋ถ๋ถ์ ๋ํด ๋๊ธ ๋จ๊ฒจ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค! ๐
'Computer Science > Database' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DB/MongoDB] BSON(Binary JSON) (0) | 2023.06.03 |
---|---|
[SQL/MySQL] ํน์ ๊ธฐ๊ฐ๋์ ๋์ฌ ๊ฐ๋ฅํ ์๋์ฐจ๋ค์ ๋์ฌ๋น์ฉ ๊ตฌํ๊ธฐ (0) | 2023.04.30 |
[SQL/MySQL] ์๊ฐ๋๋ณ ํต๊ณ ๋ด๊ธฐ (0) | 2023.04.23 |
[SQL/MySQL] Window ํจ์๋ก ํฐ ๊ฐ/์์ ๊ฐ ์กฐํํ๊ธฐ (1) | 2023.04.20 |
[MySQL] GROUP BY ์ฃผ์์ฌํญ (0) | 2023.03.29 |
๐ [ํ๋ก๊ทธ๋๋จธ์ค] ๊ทธ๋ฃน๋ณ ์กฐ๊ฑด์ ๋ง๋ ์๋น ๋ชฉ๋ก ์ถ๋ ฅํ๊ธฐ
ํ์คํ join์ชฝ ๋ฌธ์ ๊ฐ ์ด๋ ค์ด ๊ฒ ๊ฐ๋ค...
๋ฌธ์
MEMBER_PROFILE
์ REST_REVIEW
ํ
์ด๋ธ์์ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์์ฑํ ํ์์ ๋ฆฌ๋ทฐ๋ค์ ์กฐํํ๋ SQL๋ฌธ์ ์์ฑํด์ฃผ์ธ์. ํ์ ์ด๋ฆ, ๋ฆฌ๋ทฐ ํ
์คํธ, ๋ฆฌ๋ทฐ ์์ฑ์ผ์ด ์ถ๋ ฅ๋๋๋ก ์์ฑํด์ฃผ์๊ณ , ๊ฒฐ๊ณผ๋ ๋ฆฌ๋ทฐ ์์ฑ์ผ์ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์, ๋ฆฌ๋ทฐ ์์ฑ์ผ์ด ๊ฐ๋ค๋ฉด ๋ฆฌ๋ทฐ ํ
์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌํด์ฃผ์ธ์.
ํ์ด
1. ์ฒ์ ์ฝ๋
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN (SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) COUNTS) R_CNT
ON(R.MEMBER_ID = R_CNT.MEMBER_ID) JOIN MEMBER_PROFILE M
ON (R_CNT.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
2. CTE ์ฌ์ฉ (1. ์ฒ์ ์ฝ๋๋ฅผ ์ ๋ฆฌ)
- CTE๋ฅผ ์ฌ์ฉํ๋ ํจ์ฌ ๊ฐ๋ ์ฑ์ด ๋ ์ข์์ง ๊ฒ ๊ฐ๋ค.
WITH MOST_REVIEWS AS (
SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) CNT_R
)
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN MOST_REVIEWS
ON(R.MEMBER_ID = MOST_REVIEWS.MEMBER_ID)
JOIN MEMBER_PROFILE M
ON (MOST_REVIEWS.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
์์ธ ํ์ด
- ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์์ฑํ ํ์๋ค์ ์๊ธฐ ์ํด RANK() OVER๋ฅผ ์ฌ์ฉํ๋ค. ๋จผ์ ,
MEMBER_ID
๋ฅผ ๊ธฐ์ค์ผ๋ก GROUP BYํ๊ณ COUNT() ํจ์๋ฅผ ํตํดREST_ID
์ ๊ฐ์๋ฅผ ์ธ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ๊ทธ ์๋ธ์ฟผ๋ฆฌ์ CNT๋ฅผ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ์ฌ RANK๋ฅผ ๋งค๊ฒผ๋ค. - ์๋ธ์ฟผ๋ฆฌ์์ GROUP BY๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ์๋น ํ๋์ ๋ฆฌ๋ทฐ๋ง ๋ํ๋๋ค.
- ๊ฐ์ฅ ๋ง์ด ์์ฑํ ๋ฆฌ๋ทฐ ์๋ 3๊ฐ์ด๋ฉฐ 3๋ช ์ ํ์์ด ๊ฐ์ฅ ๋ง์ ๋ฆฌ๋ทฐ๋ฅผ ์์ฑํ๋ค.
WITH MOST_REVIEWS AS (
SELECT *, RANK() OVER (ORDER BY CNT DESC) AS R
FROM (SELECT *, COUNT(REST_ID) CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) CNT_R
)

REST_REVIEW
ํ ์ด๋ธ์ ์กฐ์ธํ ์ด์ ๋ ๊ฐ์ฅ ๋ฆฌ๋ทฐ๋ฅผ ๋ง์ด ๋จ๊ธด ํ์์ ๋ฆฌ๋ทฐ๊น์ง ์ถ๋ ฅํด์ผ ๋๋๋ฐMOST_REVIEWS
์์๋ ๊ฐ์ฅ ๋ง์ด ๋ฆฌ๋ทฐ๋ฅผ ๋จ๊ธด ํ์๋ง ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.MEMBER_NAME
์ ์ถ๋ ฅํ๊ธฐ ์ํดMEMBER_PROFILE
ํ ์ด๋ธ๋ ์กฐ์ธํด์ค๋ค.- RANK๊ฐ 1์ธ ์กฐ๊ฑด์ ์ค๋ค.
REVIEW_DATE
์REVIEW_TEXT
๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
SELECT MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM REST_REVIEW R JOIN MOST_REVIEWS
ON(R.MEMBER_ID = MOST_REVIEWS.MEMBER_ID)
JOIN MEMBER_PROFILE M
ON (MOST_REVIEWS.MEMBER_ID = M.MEMBER_ID)
WHERE R = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;
์ฌ๋ด
- ๋๋ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ๋จ๊ธด ํ์๋ค์ ๋ชจ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ถ๋ ฅ๋ ์ ์๊ฒ ์ฟผ๋ฆฌ๋ฅผ ์งฐ์๋ค. (3๋ช ์ด ๊ณต๋ 1์๋ก ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ผ๋ค๋ฉด ๊ทธ ํ์๋ค์ด ์ผ๋ ๋ชจ๋ ๋ฆฌ๋ทฐ๊ฐ ์ถ๋ ฅ๋๊ฒ ํ์๋ค)
- ๋ค๋ฅธ ๋ถ๋ค์ ํ์ด๋ฅผ ๋ณด๋ ๊ฐ์ฅ ๋ง์ ๋ฆฌ๋ทฐ๋ฅผ ์ผ๋ ํ์ 1๋ช
์ ๋ํ ๋ชจ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ถ๋ ฅํด๋ ์ ๋ต ์ฒ๋ฆฌ๊ฐ ๋๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ๊ทธ๋์
limit 1
์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ ๊ฒ ๊ฐ๋ค.
ํ๊ณ
- ์ฒ์ ์ฝ๋๋ฅผ ์์ฑํ ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค๋ณด๋ ๋ฒ์๊ฐ ํค๊ฐ๋ ค์ ์ค๋ฅ๊ฐ ๋ง์ด ๋ฌ์๋ค. (ex. ๊ดํธ๋ alias ๋ฑ) ๋ ๊ฐ๋ ์ฑ์ด ๋ง์ด ๋จ์ด์ ธ์ ๊ฒํ ํ ๋ ๋ถํธํ๋ค.
- ์ฒ์ ์ฝ๋๋ฅผ CTE๋ก ์์ฑํ๋ ๊ฐ๋ ์ฑ์ด ๋์์ ธ์ ๊ฒํ ํ๊ธฐ ํธํด์ก๋ค.
- ์์ง๊น์ง RANK() OVER๋ฅผ ๋ค๋ฃจ๋ ๊ฒ์ด ๋ฏธ์ํ์ฌ ์ฐ์ต์ด ํ์ํ๋ค.
- ํ๋ก๊ทธ๋๋จธ์ค ๊ฒ์ํ์์ ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค CTE๊ฐ ๋ฉด์ ์์ ์ค๋ช ํ๊ธฐ ์ฝ๊ณ ์ฝ๋ ๋ฆฌ๋ทฐ์๋ ์ข์ ์ ์๋ฅผ ๋ฐ์ ์ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ฝ๋๋ฅผ ๋ณด๋๋ผ๋ ๊ฐ๋ ์ฑ์ด ์ข์ ํธํ ๊ฒ ๊ฐ๋ค. CTE์ ์ต์ํด์ ธ์ผ ๊ฒ ๋ค. ๐ ์ฐธ๊ณ ๋งํฌ
Ref.
1. ํ๋ก๊ทธ๋๋จธ์ค (CTE ๊ด๋ จ) / https://school.programmers.co.kr/questions/45837
2. ํ๋ก๊ทธ๋๋จธ์ค (๋ฌธ์ ์๋ ๊ด๋ จ) / https://school.programmers.co.kr/questions/41349
3. RANK() OVER์ COUNT() / https://denodo1.tistory.com/355
* ์๋ชป๋ ๋ถ๋ถ์ ๋ํด ๋๊ธ ๋จ๊ฒจ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค! ๐
'Computer Science > Database' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DB/MongoDB] BSON(Binary JSON) (0) | 2023.06.03 |
---|---|
[SQL/MySQL] ํน์ ๊ธฐ๊ฐ๋์ ๋์ฌ ๊ฐ๋ฅํ ์๋์ฐจ๋ค์ ๋์ฌ๋น์ฉ ๊ตฌํ๊ธฐ (0) | 2023.04.30 |
[SQL/MySQL] ์๊ฐ๋๋ณ ํต๊ณ ๋ด๊ธฐ (0) | 2023.04.23 |
[SQL/MySQL] Window ํจ์๋ก ํฐ ๊ฐ/์์ ๊ฐ ์กฐํํ๊ธฐ (1) | 2023.04.20 |
[MySQL] GROUP BY ์ฃผ์์ฌํญ (0) | 2023.03.29 |