여러개의 상품이 있습니다.
여러 상품중에서 가격이 제일 높은 순으로 상품을 5개를 추출할려고 합니다.(상품종류는 상관없음)
이것은 RANK함수를 이용하여 추출하면 되는데..
문제는 가격이 제일 높은 순으로 상품을 5개를 추출할때 꼭 2가지 상품(예, A, Z)도 가격이 제일 높은 순으로 항상
포함이 되어야 한다는 거죠. 설령 A, Z 상품이 5개를 추출한 상품의 가격보다 작더라도 A, Z상품들 중에서 제일 높은 상품
2개는 포함이 되어야 하며, A, Z 상품이 가격이 높아 5개에 해당될 수 도 있습니다.
따라서 A, Z상품은 무조건 각 1개씩은 포함되어야 합니다. 아래의 결과는 예 입니다.
상품 가격
A 8
B 10
C 12
D 10
Z 7
A 5
Z 3
B 15
B 12
C 8
Z 5
위 값 정렬은 B,C,B,B,D,A,C,Z,A,Z,Z....
결과(5개) : B,C,B,B,D -> B,C,B,A,Z (최종 결과)
위 처럼 A,Z 상품의 제일 높은 가격이 포함되어야 합니다.
정렬을 했을 경우 A, Z 상품들이 5번째에 포함되면 되는데 그렇지 않을 경우 A, Z를 포함을 시켜야하는데
쿼리로 가능한지가 궁금합니다.
WITH T AS( SELECT 'A' a, 8 b FROM dual UNION ALL SELECT 'B', 10 FROM dual UNION ALL SELECT 'C', 12 FROM dual UNION ALL SELECT 'D', 10 FROM dual UNION ALL SELECT 'Z', 7 FROM dual UNION ALL SELECT 'A', 5 FROM dual UNION ALL SELECT 'Z', 3 FROM dual UNION ALL SELECT 'B', 15 FROM dual UNION ALL SELECT 'B', 12 FROM dual UNION ALL SELECT 'C', 8 FROM dual UNION ALL SELECT 'Z', 5 FROM dual ) SELECT a, b FROM ( SELECT T.* , CASE WHEN a IN ('A', 'Z') THEN (ROW_NUMBER() OVER(PARTITION BY a ORDER BY b DESC)) + 2 ELSE ROW_NUMBER() OVER(ORDER BY b DESC) END rn FROM T ) WHERE rn <= 3 union 쓰시면 될 것 같으나 구지 안쓰고 억지로 한다면 이정도로 하면 되려나요? 정렬은 좀 다듬고요
WITH t AS ( SELECT 'A' cd, 8 amt FROM dual UNION ALL SELECT 'B', 10 FROM dual UNION ALL SELECT 'C', 12 FROM dual UNION ALL SELECT 'D', 10 FROM dual UNION ALL SELECT 'Z', 7 FROM dual UNION ALL SELECT 'A', 5 FROM dual UNION ALL SELECT 'Z', 3 FROM dual UNION ALL SELECT 'B', 15 FROM dual UNION ALL SELECT 'B', 12 FROM dual UNION ALL SELECT 'C', 8 FROM dual UNION ALL SELECT 'Z', 5 FROM dual --UNION ALL SELECT 'Z', 16 FROM dual --UNION ALL SELECT 'Z', 16 FROM dual --UNION ALL SELECT 'Z', 16 FROM dual --UNION ALL SELECT 'Z', 16 FROM dual --UNION ALL SELECT 'Z', 16 FROM dual ) SELECT cd, amt FROM (SELECT cd, amt FROM (SELECT cd, amt , ROW_NUMBER() OVER(ORDER BY amt DESC, cd) rn1 , CASE WHEN cd IN ('A', 'Z') AND ROW_NUMBER() OVER(PARTITION BY cd ORDER BY amt DESC) = 1 THEN 1 ELSE 2 END rn2 FROM t ) WHERE rn1 <= 5 OR rn2 = 1 ORDER BY rn2, rn1 ) WHERE ROWNUM <= 5 ORDER BY amt DESC, cd ;