Pergunta

Given the following tables:

TableA

id
field1
field2
field3
field4
filed5
field6
field7
field8
field9

TableB

id
field1
field2
field3
field4
field5
statusField

I want to build a record which is comprised of fields from the above two tables. A complete record is comprised of the following fields

tableA.field1 or tableB.field1
tableA.field2 or tableB.field2
tableA.field3 or tableB.field3
tableA.field4 or tableB.field4
tableA.field5 or tableB.field5
                 tableB.field6
             tableB.field7
             tableB.field8
             tableB.field9

If the value of tableB.statusField = 'Valid' then use the value in tableB otherwise use the value in TableA. Fields 6 through to 9 are always used as they only exist in tableB.

I can think of two ways to build this query:

Approach 1

select decode(tableB.statusField, 'Valid', tableB.field1, tableA.field1), 
    decode(tableB.statusField, 'Valid', tableB.field1, tableA.field1), 
    decode(tableB.statusField, 'Valid', tableB.field2, tableA.field2), 
    decode(tableB.statusField, 'Valid', tableB.field3, tableA.field3), 
    decode(tableB.statusField, 'Valid', tableB.field4, tableA.field4), 
    decode(tableB.statusField, 'Valid', tableB.field5, tableA.field5),tableB.field6, tableB.field7, tableB.field8, tableB.field9
from tableA, tableB
where tableA.id = tableB.id

Approach 2

Select 
    case tableB.statusField when 'valid' then tableB.field1 else tableA.field1 end,
    case tableB.statusField when 'valid' then tableB.field1 else tableA.field1 end,
    case tableB.statusField when 'valid' then tableB.field2 else tableA.field2 end,
    case tableB.statusField when 'valid' then tableB.field3 else tableA.field3 end,
    case tableB.statusField when 'valid' then tableB.field4 else tableA.field4 end,
    case tableB.statusField when 'valid' then tableB.field5 else tableA.field5 end,
    tableB.field6, tableB.field7, tableB.field8, tableB.field9
from tableB, tableA
where tableB.id = tableA.id

I think one of the above approaches would work but i am having that feeling where you feel that it is just not the best way to do this.

Are there better or other alternative approaches to achieve the same? The record i want to build is comprised of 125 fields so idealy i want to avoid having 125 decode/case statements.

(I am using Oracle 11G)

Thanks

Foi útil?

Solução

I would use left outer join and coalesce:

select coalesce(b.field1, a.field1) as field1,
       coalesce(b.field2, a.field2) as field2,
       coalesce(b.field3, a.field3) as field3,
       coalesce(b.field4, a.field4) as field4,
       coalesce(b.field5, a.field5) as field5,
       coalesce(b.field6, a.field6) as field6,
       b.field7, b.field8, b.field9, b.field10       
from tableA a left outer join
     tableB b
     on a.id = b.id and
        b.statusField = 'Valid';

This assumes that none of the fields in b have NULL values. Otherwise, you need to use case instead:

select (case when b.statusField = 'Valid' then b.field1 else a.field1 end) as field1, 
       . . .

Outras dicas

As an alternative, you could try by using UNION:

Select 
    tableB.field1,
    tableB.field1,
    tableB.field2,
    tableB.field3,
    tableB.field4,
    tableB.field5,
    tableB.field6, tableB.field7, tableB.field8, tableB.field9
from tableB, tableA
where tableB.id = tableA.id and tableB.statusField='Valid'
union
Select 
    tableA.field1,
    tableA.field1,
    tableA.field2,
    tableA.field3,
    tableA.field4,
    tableA.field5,
    tableA.field6, tableB.field7, tableB.field8, tableB.field9
from tableB, tableA
where tableB.id = tableA.id and tableB.statusField<>'Valid'
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top