none
Como realizar una Consulta de Stock RRS feed

  • Pregunta

  • Buen día expertos, 

    En la siguiente imangen les envio un modelo de como quisera que se vea mi consulta en el sql server

    lo que no me resulta es el stock (cantidad existente),valores y promedio,..

    hasta el momento lo tengo la consulta de esta forma:

    smi consulta en sql server:

    CREATE VIEW ALMACEN_GENERAL
    AS
    WITH TABLA AS  (SELECT te.FECHA_ENTRADA AS Fecha,te.ID_ENTRADA_ALMACEN as Guia,ta.CODIGO AS Codigo, ta.DESCRIPCION AS Producto, 
    SUM(ted.CANTIDAD) AS Entrada, ted.PREC_UNIT AS Precio_Unitario_Entrada,SUM(ted.CANTIDAD) * ted.PREC_UNIT AS Costo_Total_Entrada,
                    NULL AS Salida, NULL AS Precio_Unitario_Salida,NULL AS Costo_Total_Salida
                    FROM REPORTEPRODUCTO AS ta 

    INNER JOIN DETALLE_ENTRADA_ALMACEN AS ted ON ta.CODIGO = ted.COD_NUEVO
                        INNER JOIN ENTRADA_ALMACEN AS te ON te.ID_ENTRADA_ALMACEN = ted.ID_ENTRADA_ALMACEN
                    GROUP BY te.FECHA_ENTRADA, te.ID_ENTRADA_ALMACEN, ta.CODIGO, ta.DESCRIPCION,ted.PREC_UNIT UNION

    SELECT tr.FECHA_SALIDA AS Fecha,tr.ID_SALIDA_ALMACEN as Guia,ta.CODIGO AS Codigo, ta.DESCRIPCION AS Producto, 
    NULL AS Entrada, NULL AS Precio_Unitario_Entrada, NULL AS Costo_Total_Entrada, 
                    SUM(tds.CANTIDAD) AS Salida,tds.PREC_UNIT AS Precio_Unitario_Salida,Sum(tds.CANTIDAD) * tds.PREC_UNIT as Costo_Total_Salida
                    FROM REPORTEPRODUCTO AS ta 
    INNER JOIN DETALLE_SALIDA_ALMACEN AS tds ON ta.CODIGO = tds.COD_NUEVO 
    INNER JOIN SALIDA_ALMACEN AS tr ON tds.ID_SALIDA_ALMACEN = tr.ID_SALIDA_ALMACEN
                    GROUP BY tr.FECHA_SALIDA, tr.ID_SALIDA_ALMACEN, ta.CODIGO, ta.DESCRIPCION, tds.PREC_UNIT)

        SELECT Fecha, Guia, Codigo, Producto, ISNULL(SUM(Entrada), 0) AS Entrada, ISNULL(Precio_Unitario_Entrada, 0) AS Precio_Unitario_Entrada, ISNULL((Costo_Total_Entrada),0) AS Costo_Total_Entrada, 
                ISNULL(SUM(Salida), 0) AS Salida,ISNULL(Precio_Unitario_Salida, 0) AS Precio_Unitario_Salida,ISNULL((Costo_Total_Salida),0) AS Costo_Total_Salida,
    (ISNULL(SUM(Entrada), 0) - ISNULL(SUM(Salida), 0)) as stock
         FROM   tabla AS tabla_1
         GROUP BY Fecha, Guia, Codigo, Producto, Precio_Unitario_Entrada, Costo_Total_Entrada, Precio_Unitario_Salida,Costo_Total_Salida,Entrada,Salida
    GO

    alguien me da una mano porfavor gracias por la atencion prestada.

    jueves, 18 de julio de 2019 20:36

Respuestas

  • Hola mario gr:

    Esto es un escenario ficticio, ya que no se tú modelo de datos. Pero

    CREATE TABLE REPORTEPRODUCTO
    (codigo      INT, 
     descripcion VARCHAR(20)
    );
    CREATE TABLE detalle_entrada_almacen
    (cod_nuevo          INT, 
     id_entrada_almacen INT, 
     fecha_entrada      DATE, 
     cantidad           INT, 
     prec_unit          INT
    );
    CREATE TABLE ENTRADA_ALMACEN
    (cod_nuevo          INT, 
     id_entrada_almacen INT, 
     fecha_entrada      DATE, 
     cantidad           INT, 
     prec_unit          INT
    );
    CREATE TABLE detalle_salida_almacen
    (cod_nuevo         INT, 
     id_salida_almacen INT, 
     fecha_salida      DATE, 
     cantidad          INT, 
     prec_unit         INT
    );
    CREATE TABLE salida_ALMACEN
    (cod_nuevo         INT, 
     id_salida_almacen INT, 
     fecha_salida      DATE, 
     cantidad          INT, 
     prec_unit         INT
    );
    GO
    INSERT INTO REPORTEPRODUCTO
    (codigo, 
     descripcion
    )
    VALUES
    (1,  'camisa'),
    (2,  'pantalon'); 
    GO
    INSERT INTO detalle_entrada_almacen
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO ENTRADA_ALMACEN
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO detalle_entrada_almacen
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190102',  20,  11),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO ENTRADA_ALMACEN
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190102',  30,  12),
    (2,  101,  '20190101',  14,  12);
    GO 
    INSERT INTO detalle_salida_almacen
    (cod_nuevo, 
     id_salida_almacen, 
     fecha_salida, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO salida_ALMACEN
    (cod_nuevo, 
     id_salida_almacen, 
     fecha_salida, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    GO

    Como ejemplo.

    Una posible solución a tu escenario, puede ser utilizar funciones de ventana.

    ;WITH TABLA
         AS (SELECT te.FECHA_ENTRADA AS Fecha, 
                    te.ID_ENTRADA_ALMACEN AS Guia, 
                    ta.CODIGO AS Codigo, 
                    ta.DESCRIPCION AS Producto, 
                    SUM(ted.CANTIDAD) AS Entrada, 
                    ted.PREC_UNIT AS Precio_Unitario_Entrada, 
                    SUM(ted.CANTIDAD) * ted.PREC_UNIT AS Costo_Total_Entrada, 
                    NULL AS Salida, 
                    NULL AS Precio_Unitario_Salida, 
                    NULL AS Costo_Total_Salida,
    			 1 as orden
             FROM REPORTEPRODUCTO AS ta
                  INNER JOIN DETALLE_ENTRADA_ALMACEN AS ted ON ta.CODIGO = ted.COD_NUEVO
                  INNER JOIN ENTRADA_ALMACEN AS te ON te.ID_ENTRADA_ALMACEN = ted.ID_ENTRADA_ALMACEN
             GROUP BY te.FECHA_ENTRADA, 
                      te.ID_ENTRADA_ALMACEN, 
                      ta.CODIGO, 
                      ta.DESCRIPCION, 
                      ted.PREC_UNIT
             UNION
             SELECT tr.FECHA_SALIDA AS Fecha, 
                    tr.ID_SALIDA_ALMACEN AS Guia, 
                    ta.CODIGO AS Codigo, 
                    ta.DESCRIPCION AS Producto, 
                    NULL AS Entrada, 
                    NULL AS Precio_Unitario_Entrada, 
                    NULL AS Costo_Total_Entrada, 
                    SUM(tds.CANTIDAD) AS Salida, 
                    tds.PREC_UNIT AS Precio_Unitario_Salida, 
                    SUM(tds.CANTIDAD) * tds.PREC_UNIT AS Costo_Total_Salida,
    			 2 as orden
             FROM REPORTEPRODUCTO AS ta
                  INNER JOIN DETALLE_SALIDA_ALMACEN AS tds ON ta.CODIGO = tds.COD_NUEVO
                  INNER JOIN SALIDA_ALMACEN AS tr ON tds.ID_SALIDA_ALMACEN = tr.ID_SALIDA_ALMACEN
             GROUP BY tr.FECHA_SALIDA, 
                      tr.ID_SALIDA_ALMACEN, 
                      ta.CODIGO, 
                      ta.DESCRIPCION, 
                      tds.PREC_UNIT)
         SELECT t.Fecha, 
                Guia, 
                Codigo, 
                Producto, 
                Entrada AS Entrada, 
                Precio_Unitario_Entrada AS Precio_Unitario_Entrada, 
                Costo_Total_Entrada AS Costo_Total_Entrada, 
                Salida AS Salida, 
                Precio_Unitario_Salida AS Precio_Unitario_Salida, 
                Costo_Total_Salida AS Costo_Total_Salida, 
    		  sum(isnull(entrada,0)-isnull(salida,0)) over (partition by codigo order by fecha, orden
    		  ROWS UNBOUNDED PRECEDING
    		  ) as stock
                
         FROM tabla t
         
    	order by Codigo, Guia, Fecha, orden

    Te he añadido una columna orden para establecer primero las entradas, aunque probablemente a ti no te sea necesario, pero para el ejemplo era mucho más visual.

    La columna de stock suma y resta las entradas o salidas que le correspondan, estableciendo como particion para volver a empezar el código de producto. 

    En la primera fila, recoge la primera entrada, y así sucesivamente va acumulando, hasta llegar a la fila donde cambia el código de producto que vuelve a empezar.

    Salida

    Espero te ayude

    OVER

    https://docs.microsoft.com/es-es/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-2017

    • Marcado como respuesta mario gr viernes, 19 de julio de 2019 13:59
    viernes, 19 de julio de 2019 4:58

Todas las respuestas

  • ¿Cuáles son las descripciones de sus TABLAS que intervienen en este reporte?

    IIslas Master Consultant SQL Server

    jueves, 18 de julio de 2019 23:00
  • Hola mario gr:

    Esto es un escenario ficticio, ya que no se tú modelo de datos. Pero

    CREATE TABLE REPORTEPRODUCTO
    (codigo      INT, 
     descripcion VARCHAR(20)
    );
    CREATE TABLE detalle_entrada_almacen
    (cod_nuevo          INT, 
     id_entrada_almacen INT, 
     fecha_entrada      DATE, 
     cantidad           INT, 
     prec_unit          INT
    );
    CREATE TABLE ENTRADA_ALMACEN
    (cod_nuevo          INT, 
     id_entrada_almacen INT, 
     fecha_entrada      DATE, 
     cantidad           INT, 
     prec_unit          INT
    );
    CREATE TABLE detalle_salida_almacen
    (cod_nuevo         INT, 
     id_salida_almacen INT, 
     fecha_salida      DATE, 
     cantidad          INT, 
     prec_unit         INT
    );
    CREATE TABLE salida_ALMACEN
    (cod_nuevo         INT, 
     id_salida_almacen INT, 
     fecha_salida      DATE, 
     cantidad          INT, 
     prec_unit         INT
    );
    GO
    INSERT INTO REPORTEPRODUCTO
    (codigo, 
     descripcion
    )
    VALUES
    (1,  'camisa'),
    (2,  'pantalon'); 
    GO
    INSERT INTO detalle_entrada_almacen
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO ENTRADA_ALMACEN
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO detalle_entrada_almacen
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190102',  20,  11),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO ENTRADA_ALMACEN
    (cod_nuevo, 
     id_entrada_almacen, 
     fecha_entrada, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190102',  30,  12),
    (2,  101,  '20190101',  14,  12);
    GO 
    INSERT INTO detalle_salida_almacen
    (cod_nuevo, 
     id_salida_almacen, 
     fecha_salida, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    INSERT INTO salida_ALMACEN
    (cod_nuevo, 
     id_salida_almacen, 
     fecha_salida, 
     cantidad, 
     prec_unit
    )
    VALUES
    (1,  100,  '20190101',  10,  10),
    (2,  101,  '20190101',  14,  12);
    GO

    Como ejemplo.

    Una posible solución a tu escenario, puede ser utilizar funciones de ventana.

    ;WITH TABLA
         AS (SELECT te.FECHA_ENTRADA AS Fecha, 
                    te.ID_ENTRADA_ALMACEN AS Guia, 
                    ta.CODIGO AS Codigo, 
                    ta.DESCRIPCION AS Producto, 
                    SUM(ted.CANTIDAD) AS Entrada, 
                    ted.PREC_UNIT AS Precio_Unitario_Entrada, 
                    SUM(ted.CANTIDAD) * ted.PREC_UNIT AS Costo_Total_Entrada, 
                    NULL AS Salida, 
                    NULL AS Precio_Unitario_Salida, 
                    NULL AS Costo_Total_Salida,
    			 1 as orden
             FROM REPORTEPRODUCTO AS ta
                  INNER JOIN DETALLE_ENTRADA_ALMACEN AS ted ON ta.CODIGO = ted.COD_NUEVO
                  INNER JOIN ENTRADA_ALMACEN AS te ON te.ID_ENTRADA_ALMACEN = ted.ID_ENTRADA_ALMACEN
             GROUP BY te.FECHA_ENTRADA, 
                      te.ID_ENTRADA_ALMACEN, 
                      ta.CODIGO, 
                      ta.DESCRIPCION, 
                      ted.PREC_UNIT
             UNION
             SELECT tr.FECHA_SALIDA AS Fecha, 
                    tr.ID_SALIDA_ALMACEN AS Guia, 
                    ta.CODIGO AS Codigo, 
                    ta.DESCRIPCION AS Producto, 
                    NULL AS Entrada, 
                    NULL AS Precio_Unitario_Entrada, 
                    NULL AS Costo_Total_Entrada, 
                    SUM(tds.CANTIDAD) AS Salida, 
                    tds.PREC_UNIT AS Precio_Unitario_Salida, 
                    SUM(tds.CANTIDAD) * tds.PREC_UNIT AS Costo_Total_Salida,
    			 2 as orden
             FROM REPORTEPRODUCTO AS ta
                  INNER JOIN DETALLE_SALIDA_ALMACEN AS tds ON ta.CODIGO = tds.COD_NUEVO
                  INNER JOIN SALIDA_ALMACEN AS tr ON tds.ID_SALIDA_ALMACEN = tr.ID_SALIDA_ALMACEN
             GROUP BY tr.FECHA_SALIDA, 
                      tr.ID_SALIDA_ALMACEN, 
                      ta.CODIGO, 
                      ta.DESCRIPCION, 
                      tds.PREC_UNIT)
         SELECT t.Fecha, 
                Guia, 
                Codigo, 
                Producto, 
                Entrada AS Entrada, 
                Precio_Unitario_Entrada AS Precio_Unitario_Entrada, 
                Costo_Total_Entrada AS Costo_Total_Entrada, 
                Salida AS Salida, 
                Precio_Unitario_Salida AS Precio_Unitario_Salida, 
                Costo_Total_Salida AS Costo_Total_Salida, 
    		  sum(isnull(entrada,0)-isnull(salida,0)) over (partition by codigo order by fecha, orden
    		  ROWS UNBOUNDED PRECEDING
    		  ) as stock
                
         FROM tabla t
         
    	order by Codigo, Guia, Fecha, orden

    Te he añadido una columna orden para establecer primero las entradas, aunque probablemente a ti no te sea necesario, pero para el ejemplo era mucho más visual.

    La columna de stock suma y resta las entradas o salidas que le correspondan, estableciendo como particion para volver a empezar el código de producto. 

    En la primera fila, recoge la primera entrada, y así sucesivamente va acumulando, hasta llegar a la fila donde cambia el código de producto que vuelve a empezar.

    Salida

    Espero te ayude

    OVER

    https://docs.microsoft.com/es-es/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-2017

    • Marcado como respuesta mario gr viernes, 19 de julio de 2019 13:59
    viernes, 19 de julio de 2019 4:58
  • buen dia Javi Fernández F, eres grande Javi...

    tu ayuda fue grande era lo que necesitaba, aunque tengo algunas consultas no me podrías dar un link o algun foro tuyo donde tengas ejemplos de almacenes(como varios almaces) y kardex se te agradeceria bastante.

    viernes, 19 de julio de 2019 13:59
  • Hola mario gr:

    De momento sólo tengo dos blogs, donde escribo, lo que me va surgiendo.

    https://javifer2.blogspot.com/

    https://javifer2.wordpress.com/

    viernes, 19 de julio de 2019 14:59