¿El cálculo en combinación no funciona?

Tengo esta unión:

UPDATE Table_Name
SET Change = isnull(tab2.Value,0) - tab1.Value 
FROM 
    (SELECT Date,ID,ID,FileName,Value FROM Table_Name WHERE FileName = 'x' AND Date = '2012-05-17') tab1
LEFT OUTER JOIN 
    (SELECT Date,ID,TradeID,FileName,Value FROM Table_Name WHERE FileName = 'x' AND Date = '2012-05-18')  tab2 
ON tab1.FileName = tab2.FileName AND 
tab1.ID = tab2.ID  AND 
tab1.ID = tab2.ID

Como puede ver, es una combinación externa izquierda. Sin embargo, cuando tengo datos para el 17 de mayo y ninguno para el 18 de mayo, el valor insertado debe ser -17th.Value (porque el cálculo general es 18th.Value - 17th.Value y 18th.Value serían cero).

Si coloco una declaración de selección justo debajo de la parte de inserción (para la depuración), esto se muestra correctamente, sin embargo, cuando elimino la declaración SELECT y hago el cálculo en la parte SET, no funciona. Termino con valores para Cambio de nulo, donde no se pudo encontrar una coincidencia para el 18 de mayo.

EDITAR: Debo agregar que no estoy seguro de si necesito LEFT JOIN o LEFT OUTER JOIN. Deseo devolver todas las filas de la pestaña 1 y, si no existe en la pestaña 2, el valor de cambio debería ser -tab1.Value, en lugar de tab2.Value - tab1.Value.

preguntado el 22 de mayo de 12 a las 17:05

Está realizando una verificación ISNULL en el primer valor, no en el segundo, ¿podría ser un problema? -

@PaulMcCowat EXISTS no le permitiría recuperar el valor de esa mesa. el no tendra NULL en el segundo campo, ya que es la tabla de origen, no la JOINmesa ed -

¿Qué valores obtienes para el cálculo donde tab2.value is NULL? -

@JNK, si inserto otro nivel de SELECT debajo de 'SET' (para la depuración) y realizo el cálculo en esta instrucción SELECT adicional, obtengo 0 en lugar de nulo, como me gustaría. Sin embargo, cuando elimino la selección y cambio el cálculo y la verificación nula a la declaración SET, sale mal. -

@user1107474 ¿Y dónde está? Table_Name en todo esto? -

1 Respuestas

DB2 no permite UPDATEs (o DELETEs) para contener combinaciones en la cláusula principal de referencia de la tabla, lo que, en mi opinión, evita ciertos tipos de problemas. Sí, soy consciente de que está en SQL Server, por lo que está intentando esto: tiendo a escribir cosas teniendo en cuenta las restricciones de DB2, eso es todo.

Suponiendo que desea actualizar las filas para el día 17, creo que lo siguiente debería funcionar. De lo contrario, especifique qué filas desea actualizar.

UPDATE Table_Name 
SET change = -value + COALESCE((SELECT nxt.value
                                FROM Table_Name nxt
                                WHERE nxt.fileName = table_name.fileName
                                AND nxt.id = table_name.id
                                AND nxt.scenarioId = table_name.scenarioId
                                AND nxt.cobDate = '2012-05-18'), 0)
WHERE fileName = 'GBP.csv'
AND cobDate = '2012-05-17'

EDIT: Errores corregidos para arriba.

Sin embargo... por el sonido de las cosas, es posible que esté intentando actualizar las filas que no existen; específicamente, el 'resultado debe ingresarse para el día 18'. Si lo que está haciendo es intentar actualizar esas filas para el 18 que existen, o insertarlas si no las hay, necesitará dos declaraciones (o tal vez una MERGE? Excepto que no los tengo en mi versión, así que no puedo ayudarte con eso):

UPDATE Table_Name
SET change = value - COALESCE((SELECT prev.value
                               FROM Table_Name prev
                               WHERE prev.fileName = table_name.fileName
                               AND prev.id = table_name.id
                               AND prev.scenarioId = table_name.scenarioId
                               AND prev.cobDate = '2012-05-17'), 0)
WHERE fileName = 'GBP.csv'
AND cobDate = '2012-05-18';

INSERT INTO Table_Name (id, scenarioId, fileName, cobDate, value, change) 
                        SELECT id, scenarioId, fileName, '2012-05-18', 0, -value
                        FROM Table_Name
                        WHERE fileName = 'GBP.csv'
                        AND cobDate = '2012-05-17'
                        AND NOT EXISTS (SELECT '1'
                                        FROM Table_Name nxt
                                        WHERE nxt.fileName = table_name.filename
                                        AND nxt.id = table_name.id
                                        AND nxt.scenarioId = table_name.scenarioId
                                        AND nxt.cobDate = '2012-05-18');

Usted DEBE ejecutarlos en ese orden.
Usted TAMBIÉN DEBE bloquear la mesa para la ejecución combinada de ambas declaraciones, tienen algún otro método para garantizar que no se modifiquen filas que contengan datos relevantes (INSERTy, UPDATEd, DELETEd), o ser capaz de decir qué filas fueron no tocado.

Si este no es el comportamiento que desea, modifique su pregunta para que sea más claro sobre lo que está tratando de lograr.

contestado el 23 de mayo de 12 a las 16:05

Hola Z-Zero, parece haber un pequeño problema con la sintaxis 'como origen' y el ',0)' (este último podría ser una consecuencia del error anterior)? - mezamórfico

Con respecto a los errores, faltaba un paréntesis después de COALESCE y no pude hacer funcionar el 'como origen'. Reemplacé "origen". esto con "Table_Name". - mezamórfico

No creo que esto sea exactamente lo que estoy buscando. El resultado de la resta en realidad debe ingresarse para el día 18 y el énfasis está en la UNIÓN IZQUIERDA. Intenté editar tu SQL pero no pude lograr que hiciera eso: s (¡probablemente mi error!) - mezamórfico

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.