2012-11-27 15 views
5

Mam tabelę A, poniżej, gdzie dla każdego unikalnego identyfikatora są trzy kody o pewnej wartości.Jak można przestawić tabelę w DB2?

ID Code Value 
--------------------- 
11  1  x 
11  2  y 
11  3  z 
12  1  p 
12  2  q 
12  3  r 
13  1  l 
13  2  m 
13  3  n 

mam drugą w tabeli B w formacie jak poniżej:

Id Code1_Val Code2_Val Code3_Val 

Tu jest tylko jeden wiersz dla każdego unikalnego identyfikatora. Chcę wypełnić tę drugą tabelę B z pierwszej tabeli A dla każdego identyfikatora z pierwszej tabeli.

Dla pierwszej tabeli A powyżej, druga tabela B powinien wyjść jak:

Id Code1_Val Code2_Val Code3_Val 
--------------------------------------------- 
11  x   y    z 
12  p   q    r 
13  l   m    n 

Jak mogę to osiągnąć w jednym zapytaniu SQL?

Odpowiedz

2

Jeśli wersja nie posiada DECODE(), można również użyć tego:

INSERT INTO B (id, code1_val, code2_val, code3_val) 
WITH Ids (id) as (SELECT DISTINCT id 
        FROM A) -- Only to construct list of ids 

SELECT Ids.id, a1.value, a2.value, a3.value 
FROM Ids -- or substitute the actual id table 
JOIN A a1 
    ON a1.id = ids.id 
     AND a1.code = 1 
JOIN A a2 
    ON a2.id = ids.id 
     AND a2.code = 2 
JOIN A a3 
    ON a3.id = ids.id 
     AND a3.code = 3 

(Działa na mojej instancji DB2 V6R1 i ma numer SQL Fiddle Example).

+0

jest sposób, aby to zrobić dynamicznie, jeśli tabela A otrzyma nowy kod lub dwa? – John

+0

Niełatwo, i potrzebujesz również dynamicznego SQL. Jestem prawie pewny, że istnieją przykłady gdzie indziej tutaj - zasadniczo, musisz przeczytać tabele schematów "informacji o systemie", zmontować zapytanie w ten sposób, a następnie wykonać je. Biorąc pod uwagę, że ogólne wstawienia do 'A' powinny być dość rzadkie, łatwiej byłoby po prostu zaktualizować instrukcje i kod klienta ... W przeciwnym razie zbliżasz się do terytorium EAV, które jest (nieco) powiązane, ale trochę inne . –

+0

[Istnieje lepsza odpowiedź, która uzyskuje dostęp do tabeli tylko raz] (https://stackoverflow.com/a/23207503/521799) –

0

Oto SQLFiddle example

insert into B (ID,Code1_Val,Code2_Val,Code3_Val) 
select Id, max(V1),max(V2),max(V3) from 
(
select ID,Value V1,'' V2,'' V3 from A where Code=1 
union all 
select ID,'' V1, Value V2,'' V3 from A where Code=2 
union all 
select ID,'' V1, '' V2,Value V3 from A where Code=3 
) AG 
group by ID 
+0

To ma być dla DB2 Konkretnie. SQLFiddle nie obsługuje DB2 ... –

+0

Tak, na pewno. To polecenie SQL jest zgodne z SQL-92, więc wszystkie DBMS muszą to wspierać. – valex

+0

Nie jest to jednak dobre zapytanie SQL dla dowolnego systemu DBMS obsługującego nawet instrukcję case, ponieważ wymaga ona więcej pracy niż jest to uzasadnione. (Grupuj według, po wykonaniu 3 wybranych i maksymalnym wywołaniu w 3 różnych kolumnach ...) –

-1

Chcesz obracać swoje dane. Ponieważ program DB2 nie ma funkcji pivot, można yo używać dekodowania (w zasadzie instrukcji case.)

Składnia powinna być:

SELECT Id, 
    DECODE(Code, 1, Value) AS Code1_Val, 
    DECODE(Code, 2, Value) AS Code2_Val, 
    DECODE(Code, 3, Value) AS Code3_Val, 
FROM A 
+2

W zależności od wersji DB2; moja wersja V6R1 (iSeries) tego nie robi. –

+0

Dzięki. Możesz zaktualizować tę instrukcję, aby użyć instrukcji case i uniknąć wielu sprzężeń. –

+1

masz "," po Code3_Val – Esperento57

5
select Id,            
     max(case when Code = '1' then Value end) as Code1_Val, 
     max(case when Code = '2' then Value end) as Code2_Val, 
     max(case when Code = '3' then Value end) as Code3_Val 
     from TABLEA          
     group by Id            
0

Oto zapytań SQL:

insert into pivot_insert_table(id,code1_val,code2_val, code3_val) 
select * from (select id,code,value from pivot_table) 
pivot(max(value) for code in (1,2,3)) order by id ; 
1
SELECT Id, 
max(DECODE(Code, 1, Value)) AS Code1_Val, 
max(DECODE(Code, 2, Value)) AS Code2_Val, 
max(DECODE(Code, 3, Value)) AS Code3_Val 
FROM A 
group by Id 
0
WITH Ids (id) as 
(
    SELECT DISTINCT id FROM A 
) 
SELECT Ids.id, 
(select sub.value from A sub where Ids.id=sub.id and sub.code=1 fetch first rows only) Code1_Val, 

(select sub.value from A sub where Ids.id=sub.id and sub.code=2 fetch first rows only) Code2_Val, 

(select sub.value from A sub where Ids.id=sub.id and sub.code=3 fetch first rows only) Code3_Val 
FROM Ids