none
Consulta de movimiento de inventario hasta una fecha especifica RRS feed

  • Pregunta

  • Saludos, necesito generar una consulta del movimiento de inventario hasta una fecha especifica, tengo dos tablas una de Inventario que tiene las columnas item, stock, movimiento de inventario, fecha y otra tabla de producto con las columnas item, nombre del producto, descripción.

    Inventario
                item                     stock                       mov_inv                          fecha
    4001 90 40 1/8/2017
    4002 70 59 30/3/2018
    4003 88 76 21/12/2017
    4004 79 45 2/6/2018
    4001 98 50 31/3/2018
    4002 100 79 1/8/2018
    4003 48 24 15/5/2017

    Producto
          item  nombre_producto descripción
    4001         Lápiz madera
    4002         Cuadernos espiralados
    4003         borradores de tinta
    4004         reglas de 90 grados
    4005         cartulinas rojas
    4006         carpetas de plástico

    La consulta debe dar el movimiento de inventario hasta una fecha especifica en este caso hasta el 31 de marzo de 2018 (es decir too lo que se ha movido hasta esa fecha si n se ha movido nada hasta esa fecha debe mostrar el ultimo movimiento registrado ), no debe haber repetidos, en el caso del item 4002, 4003 y 4004 muestra sus últimos movimientos lo que indica que el producto no ha salido o no a rotado hace ya algún tiempo


           
    item nombre_producto stock movimieto_inventario                     fecha
    4001 Lapiz 98 50 31/3/2018
    4002 Cuadernos 100 79 1/2/2018
    4003 borradores 88 76 21/12/2017
    4004 reglas 79 45 2/6/2018

    Alguien tiene la idea o el código de como realizar esto

    miércoles, 4 de abril de 2018 3:49

Respuestas

  • Hola Tron88:

    Se me ocurre esta solución:

    	SELECT A.ITEM, A.NOMBRE_PRODUCTO, 
    			CASE WHEN O.STOCK IS NULL THEN G.STOCK ELSE O.STOCK END AS STOCK,
    			CASE WHEN O.MOV_INV IS NULL  THEN G.MOV_INV ELSE O.MOV_INV END AS MOV_INV,
    			CASE WHEN O.FECHA IS NULL THEN G.FECHA ELSE O.FECHA END AS FECHA
    		FROM 
    		PRODUCTO A LEFT JOIN (
    			SELECT P.ITEM, MAX(P.FECHA) AS FECHA 
    				FROM INVENTARIO AS P
    			WHERE FECHA <= '20180331'
    			GROUP BY P.ITEM
    
    		) AS S ON S.ITEM = A.ITEM OR S.ITEM IS NULL
    			LEFT JOIN INVENTARIO O ON S.ITEM= O.ITEM AND S.FECHA = O.FECHA
    			CROSS APPLY
    		(
    			SELECT TOP(1) B.ITEM, B.STOCK, B.MOV_INV, B.FECHA FROM INVENTARIO B
    			WHERE B.ITEM = A.ITEM
    			GROUP BY B.ITEM, B.STOCK, B.MOV_INV, B.FECHA
    			HAVING 
    				B.FECHA = MAX(B.FECHA)
    			
    		) AS G

    Un saludo

    miércoles, 4 de abril de 2018 5:44
  • Otra sugerencia seria:

    with R as (
    select item, stock, mov_inv, fecha, row_number() over(partition by item order by fecha DESC) as rn
    from inventario
    where fecha < '20180401'
    )
    select P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from R inner join producto as P on P.item = R.item
    where R.rn = 1
    order by R.fecha, R.item;

    Si deseas ver en el resultado final productos que no tengan movimiento alguno entonces usa un outer join o el operador outer apply.

    with R as (
    select item, stock, mov_inv, fecha, row_number() over(partition by item order by fecha DESC) as rn
    from inventario
    where fecha < '20180401'
    )
    select P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from R right outer join producto as P on P.item = R.item and R.rn = 1
    order by R.fecha, p.item;

    -- outer apply
    select
        P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from
        producto as P
        outer apply
        (select top (1) * from inventario as R where R.item = P.item order by R.fecha DESC) as R
    order by
        R.fecha, P.item;


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    miércoles, 4 de abril de 2018 14:10

Todas las respuestas

  • Hola Tron88:

    Se me ocurre esta solución:

    	SELECT A.ITEM, A.NOMBRE_PRODUCTO, 
    			CASE WHEN O.STOCK IS NULL THEN G.STOCK ELSE O.STOCK END AS STOCK,
    			CASE WHEN O.MOV_INV IS NULL  THEN G.MOV_INV ELSE O.MOV_INV END AS MOV_INV,
    			CASE WHEN O.FECHA IS NULL THEN G.FECHA ELSE O.FECHA END AS FECHA
    		FROM 
    		PRODUCTO A LEFT JOIN (
    			SELECT P.ITEM, MAX(P.FECHA) AS FECHA 
    				FROM INVENTARIO AS P
    			WHERE FECHA <= '20180331'
    			GROUP BY P.ITEM
    
    		) AS S ON S.ITEM = A.ITEM OR S.ITEM IS NULL
    			LEFT JOIN INVENTARIO O ON S.ITEM= O.ITEM AND S.FECHA = O.FECHA
    			CROSS APPLY
    		(
    			SELECT TOP(1) B.ITEM, B.STOCK, B.MOV_INV, B.FECHA FROM INVENTARIO B
    			WHERE B.ITEM = A.ITEM
    			GROUP BY B.ITEM, B.STOCK, B.MOV_INV, B.FECHA
    			HAVING 
    				B.FECHA = MAX(B.FECHA)
    			
    		) AS G

    Un saludo

    miércoles, 4 de abril de 2018 5:44
  • Gracias, ejecute el código y funciono bien, muchas gracias, para ordenar por fecha debería agregar el order by fecha en que parte o como lo podría ordenar por fecha ?

    Adicional me podrían recomendar alguna referencia sitio web, libro, para conocer mas sobre SQL.

    Gracias

    miércoles, 4 de abril de 2018 13:58
  • Hola Tron88:

    Se me ocurre esta solución:

    	SELECT A.ITEM, A.NOMBRE_PRODUCTO, 
    			CASE WHEN O.STOCK IS NULL THEN G.STOCK ELSE O.STOCK END AS STOCK,
    			CASE WHEN O.MOV_INV IS NULL  THEN G.MOV_INV ELSE O.MOV_INV END AS MOV_INV,
    			CASE WHEN O.FECHA IS NULL THEN G.FECHA ELSE O.FECHA END AS FECHA
    		FROM 
    		PRODUCTO A LEFT JOIN (
    			SELECT P.ITEM, MAX(P.FECHA) AS FECHA 
    				FROM INVENTARIO AS P
    			WHERE FECHA <= '20180331'
    			GROUP BY P.ITEM
    
    		) AS S ON S.ITEM = A.ITEM OR S.ITEM IS NULL
    			LEFT JOIN INVENTARIO O ON S.ITEM= O.ITEM AND S.FECHA = O.FECHA
    			CROSS APPLY
    		(
    			SELECT TOP(1) B.ITEM, B.STOCK, B.MOV_INV, B.FECHA FROM INVENTARIO B
    			WHERE B.ITEM = A.ITEM
    			GROUP BY B.ITEM, B.STOCK, B.MOV_INV, B.FECHA
    			HAVING 
    				B.FECHA = MAX(B.FECHA)
    			
    		) AS G

    Un saludo, muchas gracias el código funciono perfecto, lo que quisiera es que se ordene por fecha,me puedes indicar como ?

    Gracias 

    miércoles, 4 de abril de 2018 14:00
  • Otra sugerencia seria:

    with R as (
    select item, stock, mov_inv, fecha, row_number() over(partition by item order by fecha DESC) as rn
    from inventario
    where fecha < '20180401'
    )
    select P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from R inner join producto as P on P.item = R.item
    where R.rn = 1
    order by R.fecha, R.item;

    Si deseas ver en el resultado final productos que no tengan movimiento alguno entonces usa un outer join o el operador outer apply.

    with R as (
    select item, stock, mov_inv, fecha, row_number() over(partition by item order by fecha DESC) as rn
    from inventario
    where fecha < '20180401'
    )
    select P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from R right outer join producto as P on P.item = R.item and R.rn = 1
    order by R.fecha, p.item;

    -- outer apply
    select
        P.item, P.nombre_producto, R.stock, R.mov_inv, R.fecha
    from
        producto as P
        outer apply
        (select top (1) * from inventario as R where R.item = P.item order by R.fecha DESC) as R
    order by
        R.fecha, P.item;


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    miércoles, 4 de abril de 2018 14:10
  • Hola:

    Solo tienes que hacer

    ORDER BY FECHA

    Un saludo

    miércoles, 4 de abril de 2018 14:35
  • Si muchas gracias me fue de utilidad, me podrías recomendar alguna referencia para aprender mas sobre SQL.

    miércoles, 4 de abril de 2018 17:10
  • Hola:

    Dado que estas en los foros, y si "ligas" algo de inglés, deberías de echarle un ojo a los videos de mva.microsoft.com.

    Si prefieres, en documentos html, para seguirlo a tu gusto https://www.aulaclic.es/sqlserver/index.htm

    Evidentemente, youtube esta lleno.

    Pero uff, evidentemente, depende de demasiados factores, como tu nivel, disponibilidad...etc..

    Aunque para empezar, ya tienes el camino.

    Saludos

    miércoles, 4 de abril de 2018 17:46