안녕하세요.
member라는 테이블과 cart_order테이블 2개를 조인하여
결제가 완료된 회원에 대하여 회원별 가장 많이 주문한 상품을 출력하려고 합니다.
SELECT X.memid
, Y.prdname
, Y.cnt
FROM member AS X
LEFT JOIN (
SELECT prdname, id, count(prdname) as cnt
FROM cart_order
WHERE total_price > 0
AND status in('OY')
GROUP BY prdname
) Y ON (X.memid = Y.id)
위와 같이 질의를 했는데요.
제가 원하는 결과값이 안나오고 이미지 처럼 노출이 되네요.
0825로 끝나는 회원아이디의 바엔드캡이라는 가장많이 주문한 상품을 출력하려고 합니다.
도움 부탁드려요 ㅡㅡ 늘 감사드립니다.
안녕하세요
저도 지식이 미약하여 참고만 하시면 될것 같아요 ^^
아래 쿼리는 memid별 cnt가 높은 순으로 번호를 부여 하여 처음 rank만 구하는 쿼리 입니다.
제가 oracle에서 해볼수가 없고 verticadb에서 한거라 의도만 참고만 하시면 될것 같아요
더 좋은 방식은 다른분 의견을 참고하세요..^^
select * from
(
select rank() over(partition by memid order by cnt DESC) AS RNK, memid, prdname, cnt from your_table
) A
where
A.RNK = 1
;
"회원별 가장 많이 주문한 상품"을 구하려면?
1. 그룹바이 기준이 틀렷습니다.
- 현재 : GROUP BY 상품ID
- 수정 : GROUP BY 회원ID, 상품ID
2. "가장 많이"에 해당하는 구문은
- MySQL : LIMIT
- MSSQL : TOP
- Oracle : ROWNUM
- 공통 : RANK() OVER(PARTITION BY 회원ID ORDER BY COUNT(*) DESC)
3. 아우터 조인이 필요할까요?
4. "가장많은"이 동점이라면? 어떻게 해야 할까요?
- 예) 사과도 10개 배도 10개 주문했다면?
- 결과가 어떻게 나와야 할까요?
- 둘 다 나와야 한다면? Rank
- 하나만 나와야 한다면? ROW_NUMBER 에 정렬 기준 추가.
SELECT x.memid , y.prdname , y.cnt FROM member x INNER JOIN (SELECT id, prdname , COUNT(*) cnt , RANK() OVER(PARTITION BY id ORDER BY COUNT(*) DESC ) rk , ROW_NUMBER() OVER(PARTITION BY id ORDER BY COUNT(*) DESC, prdname) rn FROM cart_order WHERE total_price > 0 AND status = 'OY' GROUP BY prdname, id ) y ON x.memid = y.id WHERE y.rn = 1 -- 동점시 다 나오도록 -- WHERE y.rn = 1 -- 동점시 하나만 선택 ;
SELECT a.* FROM (SELECT id , prdname , COUNT(*) cnt FROM cart_order WHERE total_price > 0 AND status = 'OY' GROUP BY id, prdname ) a INNER JOIN (SELECT id , MAX(cnt) cnt FROM (SELECT id , prdname , COUNT(*) cnt FROM cart_order WHERE total_price > 0 AND status = 'OY' GROUP BY id, prdname ) a GROUP BY id ) b ON a.id = b.id AND a.cnt = b.cnt ;