none
actualizar datos con valor de otra tabla RRS feed

  • Pregunta

  • saludos, estoy intentando actualizar una tabla obteniendo los datos desde otra, sin embargo, cuando ejecuto el comando, se actualizan todos los datos  y se colocan en Null y no se que podría estar haciendo mal:

    Mis parametros es que la tabla T_VENTAS es de donde obtengo la suma del producto y esta cantidad se la resto al inventario de la tabla T_PRODUCTOS en el campoc INV_DISPONIBLE.

    update T_PRODUCTOS set INV_DISPONIBLE = INV_DISPONIBLE - (select( SUM(T_VENTAS.CANTIDAD)) from T_VENTAS where T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO and T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO and T_VENTAS.TICKET = 1477)

    Sugerencias

    sábado, 28 de diciembre de 2019 21:32

Respuestas

  • Hola DewinRD:

    -- Escenario

    CREATE TABLE dbo.T_Productos (codigo int, inv_disponible int, Producto int) CREATE TABLE dbo.T_ventas (Codigo int, Producto int, Ticket int, Cantidad int) GO INSERT INTO dbo.T_Productos (codigo, inv_disponible, Producto) VALUES (1,100,101), (1,50 ,102), (1,200,103), (2,200,101); GO INSERT INTO dbo.T_Ventas (Codigo, Producto, Ticket, Cantidad) VALUES (1,101,1477,10), (1,101,1477,10), (1,101,1477,10), (1,102,1477,10), (2,101,1477,10), (2,102,1477,10), (1,101,1488,500); GO

    Este es más o menos tú escenario, con una tabla de productos y una de ventas. De la consulta que has expuesto se entiende que un producto se enlaza con ventas con Codigo y Producto, por tanto en el escenario he puesto repetidas veces producto y codigo como si fueran una clave compuesta.

    Todas las ventas excepto 1 se han expuesto a ese ticket. Y he metido una venta a un producto inexistente (es posible que no se pueda, pero para el escenario es válido).

    -- Code 1.0

    ;With cte as( SELECT(SUM(T_VENTAS.CANTIDAD)) AS CANTIDAD, T_PRODUCTOS.Codigo, T_Productos.Producto FROM T_VENTAS INNER JOIN T_PRODUCTOS ON T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO AND T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO WHERE T_VENTAS.TICKET = 1477 GROUP BY T_PRODUCTOS.Codigo, T_Productos.Producto ) SELECT * FROM CTE

    Una manera de obtener lo que solicitas, es preparando un conjunto con una tabla de expresión común donde te traes la suma de las ventas mezcladas con productos y las agrupas.

    Este sería el resultado de la query 1.0

    Aplicando esta manera a tu pregunta, el resultado podría ser:

    -- Code 2.0
    ;With cte as(
    	SELECT(SUM(T_VENTAS.CANTIDAD)) AS CANTIDAD, T_PRODUCTOS.Codigo, T_Productos.Producto
        FROM 
             T_VENTAS 
    		 INNER JOIN T_PRODUCTOS  ON 
    					T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO
    				AND T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO
    	WHERE
                T_VENTAS.TICKET = 1477
    	GROUP BY T_PRODUCTOS.Codigo, T_Productos.Producto
    )
    UPDATE P
      SET P.INV_DISPONIBLE = P.INV_DISPONIBLE - c.CANTIDAD
        FROM T_Productos P INNER JOIN CTE C ON P.Codigo = C.codigo AND P.Producto = c.Producto
    GO

    Realizar la update contra productos, mezclado con el conjunto de la tabla de expresión común.

    La salida, es que nos ha restado al producto 1-101 las 30 unidades vendidas, al 1-102 las 10. Y al 2-101 las 10 unidades vendidas.

    Tablas de expresión común

    https://javifer2.wordpress.com/2018/12/18/with-cte-tablas-de-expresion-comun-1/

    Group by

    https://javifer2.wordpress.com/2019/10/04/group-by-quizas-la-clausula-mas-conflictiva/

    • Marcado como respuesta DewinRD domingo, 29 de diciembre de 2019 14:05
    domingo, 29 de diciembre de 2019 8:57

Todas las respuestas

  • Hola

    Revise un poco y cuando la condición no se cumple te regresa un null, creo que reformularia un poco la consulta a algo así.


    update TP
    SET TP.INV_DISPONIBLE = (ISNULL(sum(TV.CANTIDAD),0))
    from T_PRODUCTOS TP
    inner join T_VENTAS TV on TV.CODIGO = TP.CODIGO
          AND TV.PRODUCTO = TP.PRODUCTO
          AND TV.TICKET = 1477

    Creando un inner join para seleccionar unicamente los datos que necesitas, ademas agregar un ISNULL para agregar un dato diferente a null en caso de que no haya coincidencia y asi puedas detectar en que datos esta tronando.

    La verdad es que no pude realizar una prueba con la consulta que propongo, pero he realizado algunas similares y funcionan bien.

    Nota: Por favor ejecuta en un ambiente de pruebas ya que no puedo asegurar nada

    Espero te sirva, saludos

    --

    Juan C

    Contacto: https://ewebik.com/


    sábado, 28 de diciembre de 2019 23:08
  • Si no se cumple en ningún registro la condición que hay en el "where" de la subconsulta, entonces el "select SUM" devuelve NULL. Y al restar INV_DISPONIBLE-NULL el resultado es NULL (no es INV_DISPONIBLE como podrías pensar). Por eso el SET graba un NULL.

    Puedes resolverlo poniendo ISNULL o COALESCE para que convierta el NULL en cero.

    update T_PRODUCTOS set INV_DISPONIBLE = INV_DISPONIBLE - COALESCE((select( SUM(T_VENTAS.CANTIDAD)) from T_VENTAS where T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO and T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO and T_VENTAS.TICKET = 1477), 0)

    domingo, 29 de diciembre de 2019 8:42
  • Hola DewinRD:

    -- Escenario

    CREATE TABLE dbo.T_Productos (codigo int, inv_disponible int, Producto int) CREATE TABLE dbo.T_ventas (Codigo int, Producto int, Ticket int, Cantidad int) GO INSERT INTO dbo.T_Productos (codigo, inv_disponible, Producto) VALUES (1,100,101), (1,50 ,102), (1,200,103), (2,200,101); GO INSERT INTO dbo.T_Ventas (Codigo, Producto, Ticket, Cantidad) VALUES (1,101,1477,10), (1,101,1477,10), (1,101,1477,10), (1,102,1477,10), (2,101,1477,10), (2,102,1477,10), (1,101,1488,500); GO

    Este es más o menos tú escenario, con una tabla de productos y una de ventas. De la consulta que has expuesto se entiende que un producto se enlaza con ventas con Codigo y Producto, por tanto en el escenario he puesto repetidas veces producto y codigo como si fueran una clave compuesta.

    Todas las ventas excepto 1 se han expuesto a ese ticket. Y he metido una venta a un producto inexistente (es posible que no se pueda, pero para el escenario es válido).

    -- Code 1.0

    ;With cte as( SELECT(SUM(T_VENTAS.CANTIDAD)) AS CANTIDAD, T_PRODUCTOS.Codigo, T_Productos.Producto FROM T_VENTAS INNER JOIN T_PRODUCTOS ON T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO AND T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO WHERE T_VENTAS.TICKET = 1477 GROUP BY T_PRODUCTOS.Codigo, T_Productos.Producto ) SELECT * FROM CTE

    Una manera de obtener lo que solicitas, es preparando un conjunto con una tabla de expresión común donde te traes la suma de las ventas mezcladas con productos y las agrupas.

    Este sería el resultado de la query 1.0

    Aplicando esta manera a tu pregunta, el resultado podría ser:

    -- Code 2.0
    ;With cte as(
    	SELECT(SUM(T_VENTAS.CANTIDAD)) AS CANTIDAD, T_PRODUCTOS.Codigo, T_Productos.Producto
        FROM 
             T_VENTAS 
    		 INNER JOIN T_PRODUCTOS  ON 
    					T_VENTAS.CODIGO = T_PRODUCTOS.CODIGO
    				AND T_VENTAS.PRODUCTO = T_PRODUCTOS.PRODUCTO
    	WHERE
                T_VENTAS.TICKET = 1477
    	GROUP BY T_PRODUCTOS.Codigo, T_Productos.Producto
    )
    UPDATE P
      SET P.INV_DISPONIBLE = P.INV_DISPONIBLE - c.CANTIDAD
        FROM T_Productos P INNER JOIN CTE C ON P.Codigo = C.codigo AND P.Producto = c.Producto
    GO

    Realizar la update contra productos, mezclado con el conjunto de la tabla de expresión común.

    La salida, es que nos ha restado al producto 1-101 las 30 unidades vendidas, al 1-102 las 10. Y al 2-101 las 10 unidades vendidas.

    Tablas de expresión común

    https://javifer2.wordpress.com/2018/12/18/with-cte-tablas-de-expresion-comun-1/

    Group by

    https://javifer2.wordpress.com/2019/10/04/group-by-quizas-la-clausula-mas-conflictiva/

    • Marcado como respuesta DewinRD domingo, 29 de diciembre de 2019 14:05
    domingo, 29 de diciembre de 2019 8:57
  • El query 2.0 es exactamente lo que andaba buscando Javi..... Muchas gracias por tu amable ayuda. Saludos Desde Rep.Dominicana!!!
    domingo, 29 de diciembre de 2019 14:05
  • De nada.

    Saludos desde España

    domingo, 29 de diciembre de 2019 14:20