rownumber / partition by 시 case when 적용 1 7 2,920

by 상블리 [2021.01.05 16:49:44]


ex) 칼럼이 두 개 있습니다. 하나는 학생규모(emp)이고,  나머지 하나는 선호도(like)입니다.(1,2,3,4,5) 

학생규모별 가장 선호하는 값을 rownumber, partion by로 조회 하려 합니다. 

단, emp를 그대로 사용하지 않고  

emp <= 10  then 'e1' , else 'e2 이렇게 case when을 이용하여 범위별 카데고리를 하나 추가 해서 만들고 싶습니다.  

어떻게 구문을 짜야 아래 두 번째 표처럼 값이 나올까요?? ㅠㅠ

emp like
4 1
10 2
7 3
5 3
102 5
1035 5
54 5
228 5
30 4

  

 

size like
e1 3
e2 5

 

by 마농 [2021.01.05 19:17:19]
SELECT size
     , MAX(like) like
  FROM (SELECT emp
             , like
             , CASE WHEN emp <= 10 THEN 'e1' ELSE 'e2' END size
          FROM t
        ) a
 GROUP BY size
;

1. LIKE 나 SIZE 와 같은 예약어를 컬럼명으로 하는 것은 좋지 않습니다.
 - 다른 명칭을 사용하세요.
2. 결과를 얻기 위한 수단을 제한하는 것은 좋지 않습니다.
 - rownumber 나 partion by 는 불필요해 보입니다.


by 상블리 [2021.01.05 19:33:48]

답변감사합니다. ㅠ ㅠ

다름이  최댓값이 아니라 size별 like 빈도가 가장 많이 나오는 것을 조회 하고 싶거든요(size 별 최빈값).  제가 질문을 정확히 올리지 않았네요;

송구스럽지만  최빈값 조회  하는 법 부탁드리겠습니다.. 

 


by 마농 [2021.01.06 07:49:43]

빈도가 많은 값이 동률로 두개 이상 나온다면? 어떻게 표현해야 하나요?


by pajama [2021.01.06 01:27:14]

예전에 저도 비슷한 질문한 적이 있었는데 마농님 주신 답변 참고해서 만들어 봤습니다.

 

with t as (
select 4 emp, 1 lk from dual union all
select 10   , 2    from dual union all
select 7    , 3    from dual union all
select 5    , 3    from dual union all
select 102  , 5    from dual union all
select 1035 , 5    from dual union all
select 54   , 5    from dual union all
select 228  , 5    from dual union all
select 30   , 4    from dual
)
SELECT *
  FROM ( SELECT sz
              , lk
              , ROW_NUMBER() OVER (PARTITION BY sz ORDER BY cnt DESC) rn
          FROM (SELECT sz
                     , lk
                     , COUNT(*) OVER (PARTITION BY sz, lk) cnt
                  FROM (SELECT lk
                             , CASE WHEN emp <= 10 THEN 'e1' ELSE 'e2' END sz
                          FROM t
                       ) a
               )
        )
WHERE rn = 1
;

by 상블리 [2021.01.14 19:56:59]

감사합니다~~~ 덕분에 해결되었습니다.  중첩문으로 partition 을 사용하니 원하는 결과가 나왔습니다.

 


by 마농 [2021.01.06 07:55:14]
WITH t AS
(
SELECT 4 emp, 1 lk FROM dual
UNION ALL SELECT   10, 2 FROM dual
UNION ALL SELECT    7, 3 FROM dual
--UNION ALL SELECT    5, 3 FROM dual    -- 동점 발생 테스트
UNION ALL SELECT  102, 5 FROM dual
UNION ALL SELECT 1035, 5 FROM dual
UNION ALL SELECT   54, 5 FROM dual
UNION ALL SELECT  228, 5 FROM dual
UNION ALL SELECT   30, 4 FROM dual
)
SELECT sz
     , LISTAGG(lk, ',') WITHIN GROUP(ORDER BY lk) lk
  FROM (SELECT sz, lk
             , RANK() OVER(PARTITION BY sz ORDER BY COUNT(*) DESC) rk
          FROM (SELECT lk
                     , CASE WHEN emp <= 10 THEN 'e1' ELSE 'e2' END sz
                  FROM t
                )
         GROUP BY sz, lk
        )
 WHERE rk = 1
 GROUP BY sz
;

 


by 상블리 [2021.01.14 19:57:18]

마농님 매번 감사합니다~~~ 덕분에 해결되었습니다.  중첩문으로 partition 을 사용하니 원하는 결과가 나왔습니다. ^^

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입