2017-09-28 9 views
1

J'ai une instruction d'insertion de requête comme indiqué ci-dessousautre approche pour la déclaration de cas dans l'oracle

insert into my_table 
select col1,col2,CASE 
    WHEN EXISTS 
     (SELECT 1 FROM Table_A m WHERE m.COLA='XXX' AND m.id=b.id 
    ) 
    THEN 
     (SELECT m.COLB FROM Table_A m WHERE m.COLA='XXX' AND m.id=b.id 
    ) 
    ELSE 'Not Open' 
    END XXX, 
    CASE 
    WHEN EXISTS 
     (SELECT 1 FROM Table_A m WHERE m.COLA='YYY' AND m.id=b.id 
    ) 
    THEN 
     (SELECT m.COLB FROM Table_A m WHERE m.COLA='YYY' AND m.id=b.id 
    ) 
    ELSE 'Not Open' 
    END YYY, 
    . 
    . 
    . 
    . 
    . -- ~150 case statement 
    from Test b,table_main c 
    where b.id=c.id 

Ici, nous avons relevé de cas qui fait référence même table (TABLE_A), mais la vérification des valeurs différentes (XXX, YYY, etc. ..,) dans chaque déclaration. Cela prend tellement de temps. Nous essayons d'optimiser cette requête insert. Quelqu'un pourrait-il aider ici?

+0

pouvez-vous s'il vous plaît afficher les données de table de l'échantillon? On dirait que vous avez besoin d'une autre table de rejoindre peut-être? – OldProgrammer

+0

Peut-il y avoir plusieurs enregistrements dans Table_A pour la condition m.id = b.id et m.COLA = 'any value'? –

Répondre

0

Réécrire en utilisant decode et LEFT JOIN comme suit.

SELECT col1, col2 , 
    decode (m.COLA , 'XXX' , m.COLB , 'Not Open') XXX , 
    decode (m.COLA , 'YYY', m.COLB , 'Not Open') YYY , 
    ... 
    ... 
    FROM Test b LEFT JOIN Table_A m ON m.id=b.id JOIN table_main c 
    ON b.id=c.id; 
1

Essayer une variation d'une requête de pivot:

SELECT col1, col2 , 
    coalesce (max(CASE WHEN m.COLA='XXX' THEN m.COLB END), 'Not open') As XXX, 
    coalesce (max(CASE WHEN m.COLA='YYY' THEN m.COLB END), 'Not open') As YYY, 
    ..... 
    .....  
    coalesce (max(CASE WHEN m.COLA='ZZZ' THEN m.COLB END), 'Not open') As ZZZ 
FROM Test b 
JOIN table_main c ON b.id=c.id 
LEFT JOIN Table_A m ON m.id=b.id 
GROUP BY col1, col2 
+0

Cela a presque fonctionné .. sauf quand 'm.COLB' est NULL il devrait me donner NULL mais pas 'Non ouvert'. Peut-on aider ici? – Crazy2crack

+0

Remplacez simplement la chaîne 'not open' par 'is null' dans l'appripriate rów dans la clause select – krokodilko

+0

En fait, M.COLB sera un peu' varchar' la plupart du temps et seulement parfois il sera vide. Donc, seulement quand il est vide, il devrait fournir «null» au lieu de «non ouvert». – Crazy2crack

-1

Il prend du temps parce que vous faites plusieurs appels à une table pour obtenir vos valeurs. Il suffit de réduire le nombre d'appels en cours à Table_A.

Si la condition Table_A.id = m.id et m.COLA = « Toute valeur » renvoie toujours une ligne, vous pouvez joindre les tables TABLE_A, Test et Table_main en un seul rejoindre comme ci-dessous

Insert into my_table(col1, col2) values 
select 
decode(a.COLA,'XXX' , a.COLB , 'Not Open'), 
decode(a.COLA,'YYY' , a.COLB , 'Not Open'), 
... 
... 
from Table_A a, Test b, Table_main c 
where a.id = b.id 
and b.id = c.id 

Dans le cas où la condition peut retourner plusieurs enregistrements alors vous pouvez utiliser avec clause comme ci-dessous

Insert into my_table(col1, col2) values 
with table_a as (select col1, col2 , a.COLA, a.COLB 
from Table_A a, Test b, Table_main c 
where a.id = b.id 
and b.id = c.id 
group by col1, col2,a.COLA, a.COLB) 
select col1,col2, 
decode(x.COLA,'XXX' , x.COLB , 'Not Open'), 
decode(x.COLA,'YYY' , x.COLB , 'Not Open'), 
.... 
.... 
from table_a x 
+0

Tout en marquant -ve à toute réponse, s'il vous plaît fournir la raison de la même chose. Cela aidera à comprendre ce qui a été mal posé et ne devrait pas être répété. –