2012-04-30 14 views
6

Creo que puedo optimizar este enunciado sql usando una declaración de caso para las uniones externas izquierdas.Optimización SQL Declaración de caso

Pero he estado teniendo dificultades para configurar los casos, uno para resumir los tipos de código AB, CD y otro para Todo lo demás.

Apreciar cualquier ayuda o consejo que pueda darme sobre esto.

update billing set payments = isnull(bd1.amount, payments) 
, payments = case 
     when payments is null then 0 
     else payments 
    end 
, charges = case 
     when bd2.amount is not null then charges 
     when charges is null then 0 
     else charges 
     end 
, balance = round(charges + isnull(bd1.amount, bi.payments), 2) 
from billing bi 

left outer join (select inv, round(sum(bd1.bal), 2) amount 
       from "bill" bd1 
       where code_type = 'AB' 
       or code_type = 'CD' 
       group by inv) bd1 
       on bd1.inv = bi.inv 
left outer join (select invoice, round(sum(bd2.bal), 2) amount 
       from "bill" bd2 
       where code_type <> 'AB' 
       and code_type <> 'CD' 
       group by inv) bd2 
       on bd2.inv = bi.inv; 
+3

¿Es esto válido? Parece que está actualizando la columna 'payments' dos veces. –

+0

@Siva Estoy usando Advantage 9 – Trevor

Respuesta

5

Puede simplificarlo para usar una única consulta en lugar de dos. Aún necesita el uno porque GROUP BY en una actualización no funciona.

UPDATE bi 
SET payments = bd.payments, 
     charges= bd.charges, 
     balance = bd.balance 
FROM billing bi 
     LEFT JOIN (SELECT bd.inv, 
         payments = Round(Sum(CASE 
               WHEN code_type IN ('AB' , 'CD') THEN 
               bd.bal 
               ELSE 0 
               END), 2), 
         charges = Round(Sum(CASE 
               WHEN code_type NOT IN ('AB' , 'CD') THEN 
               bd.bal 
               ELSE 0 
              END), 2), 
         balance = Round(Sum(bd.bal), 2) 
        FROM bill bd 
        GROUP BY bd.inv) bd 
     ON bd.inv = bi.inv 
+0

No es una sintaxis válida. No puede tener una función de agregado directamente en la lista de conjuntos. – GarethD

+0

@GarethD sí, es por eso que lo arreglé, vea mi última edición –

+0

Sí, lo siento, empecé a escribir el comentario, y luego comprobé que estaba 100% seguro de que no era válido, así que cuando publiqué ya lo había arreglado . Puede mejorar esto aún más usando 'CASE WHEN Code_Type IN ('AB', 'CD')' En lugar de 'Code_Type = 'AB' O Code_Type = 'CD'' – GarethD

1

Tal vez algo como esto:

update billing set payments = isnull(bd1.amount, payments) 
, payments = isnull(payments, 0) 
, charges = isnull(bd2.amount, isnull(charges, 0)) 
, balance = round(charges + isnull(bd1.amount, bi.payments), 2) 
from billing bi 

left outer join (select inv, round(sum(bd1.bal), 2) amount 
       from "bill" bd1 
       where code_type in ('AB', 'CD') 
       group by inv) bd1 
       on bd1.inv = bi.inv 
left outer join (select invoice, round(sum(bd2.bal), 2) amount 
       from "bill" bd2 
       where code_type not in ('AB', 'CD') 
       group by inv) bd2 
       on bd2.inv = bi.inv; 

Los dos izquierda se une no son un problema!

Cuestiones relacionadas