2010-08-12 10 views
25

Tengo 3 tablas (simplificado):SQL Server con combinación interna

tblOrder(OrderId INT) 
    tblVariety(VarietyId INT,Stock INT) 
    tblOrderItem(OrderId,VarietyId,Quantity INT) 

Si realizo un pedido, se me cae el nivel de stock de utilizar este:

UPDATE tblVariety 
SET tblVariety.Stock = tblVariety.Stock - tblOrderItem.Quantity 
FROM tblVariety 
INNER JOIN tblOrderItem ON tblVariety.VarietyId = tblOrderItem.VarietyId 
INNER JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId 
WHERE tblOrder.OrderId = 1 

Todo bien, hasta que haya hay dos filas en tblOrderItem con el mismo VarietyId para el mismo OrderId. En este caso, solo una de las filas se usa para la actualización de stock. Parece que está haciendo un GROUP BY VarietyId allí de alguna manera.

¿Alguien puede arrojar algo de luz? Muchas gracias.

+0

en caso de que sea imposible tener la misma combinación/orden de la variedad? Es decir, si aparece la misma Variedad> 1 para una orden, esta se captura en la columna Cantidad, no en varias filas? – gbn

+0

Técnicamente, sí. Pero hay otras columnas en tblOrderItem lo que significa que más de una línea puede entrar con esos mismos números básicos (un campo de fecha por ejemplo) – Geoff

Respuesta

43

Supongo que, debido a que nos ha mostrado un esquema simplificado, falta información que determinaría por qué tienen los valores de VarietyID repetidos para un OrderID determinado.

Cuando tiene varias filas, SQL Server seleccionará arbitrariamente una de ellas para la actualización.

Si este es el caso, es necesario agrupar primera

UPDATE V 
SET 
    Stock = Stock - foo.SumQuantity 
FROM 
    tblVariety V 
    JOIN 
    (SELECT SUM(Quantity) AS SumQuantity, VarietyID 
    FROM tblOrderItem 
     JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId 
    WHERE tblOrder.OrderId = 1 
    GROUP BY VarietyID 
    ) foo ON V.VarietyId = foo.VarietyId 

Si no es así, entonces el PK tabla de pedido es erróneo porque si permite duplicar combinaciones IDPedido/VarietyID (PK debe ser IDPedido/VarietyID, o estos deben ser restringidos única)

+0

Muchas gracias gbn - esto lo hizo por mí ... – Geoff

+0

+1 para resolverlo todo camino. – Tobiasopdenbrouw

+1

+100 @gbn Te debo una cerveza. –

1

Usted está haciendo una actualización. Se actualizará una vez.

Editar: para resolver, puede agregar una subconsulta que agrupará sus artículos de pedido por orderid y varietyid, con una suma sobre la cantidad.

12

de la documentación UPDATE

los resultados de una instrucción UPDATE son indefinido si la instrucción incluye una cláusula FROM que no está especificado en de tal manera que sólo un valor es disponible para cada aparición columna que se actualiza (en otras palabras, si la instrucción UPDATE no es determinista). Por ejemplo, dada la declaración actualización en el siguiente secuencia de comandos, ambas filas de la tabla s cumplen los calificaciones de la cláusula FROM en la instrucción UPDATE, pero es indefinido qué fila de s se utiliza para actualización de la fila en la mesa t.

CREATE TABLE s (ColA INT, ColB DECIMAL(10,3)) 
GO 
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3)) 
GO 
INSERT INTO s VALUES(1, 10.0) 
INSERT INTO s VALUES(1, 20.0) 
INSERT INTO t VALUES(1, 0.0) 
GO 
UPDATE t 
SET t.ColB = t.ColB + s.ColB 
FROM t INNER JOIN s ON (t.ColA = s.ColA) 
GO 
Cuestiones relacionadas