group | date | data1 | data2 | |
a | 2016-04-01 | … | … | |
a | 2016-01-01 | … | … | |
a | 2016-02-01 | … | … | |
a | 2016-02-16 | … | … | |
a | 2016-03-01 | … | … | |
b | 2016-03-01 | … | … | |
b | 2016-04-01 | … | … | |
b | 2016-02-16 | … | … | |
b | 2016-02-01 | … | … | |
b | 2016-01-01 | … | … |
결과
group | date | data1 | data2 | |
a | 2016-04-01 | … | … | |
b | 2016-04-01 | … | … |
group 명으로 group by 되어 진 것 중에 날짜가 가장 최신인 데이터의 한줄만 가져 오는 쿼리를 만들고 싶습니다.
max keep 문제 인것 같긴 하나 group by 가 생겨서 해결을 못하는 경우 입니다 ㅜ
본 쿼리가 어떻게 되는지 모르겠으나 기술할 컬럼이 많다면
max keep 보다 row_number over를 쓰시는 게 나아 보여요..
with t as (select 'a' gp, '2016-04-01' dt from dual union all select 'a' gp, '2016-01-01' dt from dual union all select 'a' gp, '2016-02-01' dt from dual union all select 'b' gp, '2016-03-01' dt from dual union all select 'b' gp, '2016-04-01' dt from dual ) SELECT * FROM (SELECT gp , dt , ROW_NUMBER () OVER (PARTITION BY gp ORDER BY dt DESC) rn FROM t) WHERE rn = 1
참고해서 작성해보세요.
with t as (select 'a' gp, '2016-04-01' dt, '2016-09-01' dt2 from dual union all select 'a' gp, '2016-01-01' dt, '2016-03-01' dt2 from dual union all select 'a' gp, '2016-02-01' dt, '2016-06-01' dt2 from dual union all select 'b' gp, '2016-03-01' dt, '2016-07-01' dt2 from dual union all select 'b' gp, '2016-04-01' dt, '2016-08-01' dt2 from dual ) SELECT gp , max(dt) , max(dt2) keep(dense_rank last order by dt) dt2 FROM t group by gp
max keep 으로는 이렇게 하면 될 것 같은데 컬럼이 많을 수록 좀 보기가 안좋아질 것 같아서요.
그리고 dt가 동일하고 dt2가 불일치하는 데이터가 있을 경우의 처리 문제도 있구요.
성능은 어느 게 좋을지 잘 모르겠네요.
--참고로 keep은 with t(gp, dt, data) as ( select 'a', '2016-04-01','a' from dual union all select 'a', '2016-01-01','b' from dual union all select 'a', '2016-02-01','c' from dual union all select 'a', '2016-02-16','d' from dual union all select 'a', '2016-03-01','e' from dual union all select 'b', '2016-03-01','a' from dual union all select 'b', '2016-04-01','b' from dual union all select 'b', '2016-02-16','c' from dual union all select 'b', '2016-02-01','d' from dual union all select 'b', '2016-01-01','e' from dual ) select gp ,max(dt) dt , max(data) keep(DENSE_RANK LAST ORDER BY dt) data from t group by gp;