2011-12-09 5 views
1

행을 변경 I 다음 표 foo라는이 있습니다오라클 그룹/열

ID | KEY | VAL 
---------------- 
1 | 47 | 97 
2 | 47 | 98 
3 | 47 | 99 
4 | 48 | 100 
5 | 48 | 101 
6 | 49 | 102 

내가 선택 쿼리를 실행하려면 결과는 기본적으로 모든, 그래서이

UNIQUE_ID  | KEY | ID1 | VAL1 | ID2 | VAL2 | ID3 | VAL3 
-------------------------------------------------------------- 
47_1:97_2:98_3:99| 47 | 1 | 97 | 2 | 98 | 3 | 99 
48_4:100_5:101 | 48 | 4 | 100 | 5 | 101 |  | 
49_6:102   | 49 | 6 | 102 |  |  |  | 

처럼 보여이를 동일한 KEY를 가진 행은 1 행으로 축소됩니다. KEY 값당 1-3 개의 행이있을 수 있습니다.

저장 프로 시저 또는 스크립트를 작성하지 않고 SQL 쿼리에서이 작업을 수행 할 수 있습니까?

하지 않으면, 나는 또한

UNIQUE_ID  | KEY | IDS | VALS 
-------------------------------------------------------------- 
47_1:97_2:98_3:99| 47 | 1,2,3 | 97,98,99 
48_4:100_5:101 | 48 | 4,5 | 100, 101 
49_6:102   | 49 | 6  | 102 

감사의 덜 바람직한 선택으로 일할 수있는!

UPDATE :

는 불행하게도 내 실제 문제는이 예보다 훨씬 더 어려운 것 같다, 나는 그것이 매우 쉬운 일이 아닙니다, 그래서 내 쿼리가 120 라인이다 :(일 예 중 하나를 얻는 데 문제가 . 게시 그것은 일종의 같이 보인다 :

with v_table as (select ...), 
    v_table2 as (select foo from v_table where...), 
    v_table3 as (select foo from v_table where ...), 
    ... 
    v_table23 as (select foo from v_table where ...) 
    select distinct (...) as "UniqueID", myKey, myVal, otherCol1, ..., otherCol18 
    from tbl1 inner join tbl2 on... 
    ... 
    inner join tbl15 on ... 

내가 반환되는 때문에 다른 모든 데이터를 올바르게 그룹 총격 사건을 할 수없는 것으로 보인다 이하 나는 방법을 시도 할 경우 예 :.

with v_table as (select ...), 
    v_table2 as (select foo from v_table where...), 
    v_table3 as (select foo from v_table where ...), 
    ... 
    v_table23 as (select foo from v_table where ...) 
    select "Unique ID", 
    myKey, max(decode(id_col,1,id_col)) as id_1, max(decode(id_col,1,myVal)) as val_1, 
    max(decode(id_col,2,id_col)) as id_2,max(decode(id_col,2,myVal)) as val_2, 
    max(decode(id_col,3,id_col)) as id_3,max(decode(id_col,3,myVal)) as val_3 
    from (
    select distinct (...) as "UniqueID", myKey, row_number() over (partition by myKey order by id) as id_col, id, myVal, otherCol1, ..., otherCol18 
    from tbl1 inner join tbl2 on... 
    ... 
    inner join tbl15 on ... 
) group by myKey; 

오류 : ORA-00979 : GROUP BY가 아님

이것은 내부 선택에서 고유 ID를 선택하기 때문입니다. 내부 테이블에서 다른 열을 선택하는 것뿐만 아니라이를 수행해야 할 것입니다.

도움이 될 것입니다.

+0

사용중인 Oracle 버전은 무엇입니까? – CloudyMarble

+0

Oracle 11g – user973479

+0

@ user973479를 사용하고 있습니다. - 외부 쿼리의'group by' 절에''UniqueID ''가 필요합니다. 별칭을 따옴표로 묶고 싶은 이유를 모르지만 여전히 작동해야합니다. 또한 키 생성에서 'distinct'에 대해 확신 할 수 없지만 외부 쿼리에서'otherCol1' 등이 선택되지 않아서 보이지 않을 것이고, 선택되면 '그룹별로 '있어야 할 것이다. –

답변

2

당신이

select key, 
    max(decode(id_col,1,id_col)) as id_1,max(decode(id_col,1,val)) as val_1, 
    max(decode(id_col,2,id_col)) as id_2,max(decode(id_col,2,val)) as val_2, 
    max(decode(id_col,3,id_col)) as id_3,max(decode(id_col,3,val)) as val_3 
from (
     select key, row_number() over (partition by key order by id) as id_col,id,val 
     from your_table 
    ) 
group by key 
4

에 대한 Listagg 기능을 살펴의 ATH this article을 가지고하려고 할 수 있습니다, 이것은 당신이 그것은 단지 11g 버전에서 작동, 쉼표 결과를 분리 얻는 데 도움이 될 것입니다.

2

@ O.D.

with foo as (
select 1 as id, 47 as key, 97 as val from dual 
union select 2,47,98 from dual 
union select 3,47,99 from dual 
union select 4,48,100 from dual 
union select 5,48,101 from dual 
union select 6,49,102 from dual 
) 
select unique_id, key, 
    max(id1) as id1, max(val1) as val1, 
    max(id2) as id2, max(val2) as val2, 
    max(id3) as id3, max(val3) as val3 
from (
    select unique_id,key, 
     case when r = 1 then id end as id1, case when r = 1 then val end as val1, 
     case when r = 2 then id end as id2, case when r = 2 then val end as val2, 
     case when r = 3 then id end as id3, case when r = 3 then val end as val3 
    from (
     select key ||'_'|| listagg(id ||':' ||val, '_') 
       within group (order by id) over (partition by key) as unique_id, 
      key, id, val, 
      row_number() over (partition by key order by id) as r 
     from foo 
    ) 
) 
group by unique_id, key 
order by key; 

UNIQUE_ID   KEY ID1 VAL1 ID2 VAL2 ID3 VAL3 
----------------- ---- ---- ---- ---- ---- ---- ---- 
47_1:97_2:98_3:99 47 1 97 2 98 3 99 
48_4:100_5:101  48 4 100 5 101 
49_6:102   49 6 102 
: 당신이 원하는 결과를 얻을 수 있습니다 좀 더 조작으로

with foo as (
select 1 as id, 47 as key, 97 as val from dual 
union select 2,47,98 from dual 
union select 3,47,99 from dual 
union select 4,48,100 from dual 
union select 5,48,101 from dual 
union select 6,49,102 from dual 
) 
select key ||'_'|| listagg(id ||':' ||val, '_') 
     within group (order by id) as unique_id, 
    key, 
    listagg(id, ',') within group (order by id) as ids, 
    listagg(val, ',') within group (order by id) as vals 
from foo 
group by key 
order by key; 

UNIQUE_ID   KEY IDS     VALS 
----------------- ---- -------------------- -------------------- 
47_1:97_2:98_3:99 47 1,2,3    97,98,99 
48_4:100_5:101  48 4,5     100,101 
49_6:102   49 6     102 

: 당신이 (당신의 샘플 데이터를 생성하는 CTE를 사용하여) 예를 들어, LISTAGG으로 덜 바람직한 버전을 생성 할 수 있습니다, 제안

더 간단한 방법이 있어야한다고 느끼는 데 도움이 될 수는 없습니다 ...