2012-11-27 11 views
5

Ho la tabella A, sotto, dove per ogni ID univoco, ci sono tre codici con un certo valore.Come posso ruotare una tabella in 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 

Ho una seconda tabella B con il formato come sotto:

Id Code1_Val Code2_Val Code3_Val 

Qui c'è solo una riga per ogni ID univoco. Voglio popolare questa seconda tabella B dalla prima tabella A per ogni ID dalla prima tabella.

Per la prima tabella A di cui sopra, la seconda tabella B dovrebbe uscire come:

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

Come posso raggiungere questo obiettivo in una singola query SQL?

risposta

2

Se la versione non ha DECODE(), è anche possibile utilizzare questo:

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 

(Funziona sulla mia istanza DB2 V6R1 e ha un SQL Fiddle Example).

+0

c'è un modo per farlo dinamicamente se la tabella A ottiene un nuovo codice o due? – John

+0

Non facilmente, e avresti anche bisogno di SQL dinamico. Sono abbastanza sicuro che ci siano degli esempi altrove qui - in sostanza, devi leggere le tabelle dello schema 'information system', assemblare la query in questo modo, quindi eseguirla. Dato che gli inserimenti generali a 'A' dovrebbero essere piuttosto rari, sarebbe probabilmente più semplice aggiornare semplicemente le istruzioni e il codice cliente ... Altrimenti, stai rasentando il territorio dell'EAV, che è (in qualche modo) correlato ma un po 'diverso . –

+0

[C'è una risposta migliore che accede alla tabella solo una volta] (https://stackoverflow.com/a/23207503/521799) –

0

Ecco un 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

Questo dovrebbe essere per DB2 particolare. SQLFiddle non supporta DB2 ... –

+0

Sì, certo. Questo comando SQL è compatibile con SQL-92, quindi tutti i DBMS devono supportarlo. – valex

+0

Ma non è una buona query SQL per qualsiasi DBMS che supporti anche un'istruzione case, perché deve fare molto più lavoro di quanto sia garantito. (Raggruppa per, dopo aver effettuato 3 selezioni e una chiamata massima su 3 diverse colonne ...) –

-1

Si vuole ruotare i dati. Dal momento che DB2 non ha alcuna funzione pivot, yo può utilizzare Decode (in pratica una dichiarazione caso.)

La sintassi dovrebbe essere:

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

Dipende dalla versione di DB2; la mia versione V6R1 (iSeries) no. –

+0

Grazie. È possibile aggiornare questa dichiarazione per utilizzare un'istruzione case ed evitare più join. –

+1

hai un "," dopo 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

Qui è la query 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