none
Consulta: Select SQL para saldo de Kardex RRS feed

  • Pregunta

  • Estimado Colegas.

    Se requiere de una consulta de la siguiente forma.

     

    ITEM --- ARTICULO --- TIPOMOV --- CANTIDAD  ------<SALDO>

    1236    CAMISA        01-INGRESO      20                  <20>

    1236    CAMISA        01-INGRESO      10                  <30>

    1236    CAMISA        02-SALIDA         5                    <25>

    1236    CAMISA        01-INGRESO      15                  <40>

    1236    CAMISA        02-SALIDA         10                  <30>

     

    Mi pregunta es como tendria que realizar el select para generar el campo saldo.

    Gracias por su ayuda


    saludos

     


    Rolando Lau Project Management
    jueves, 26 de enero de 2012 19:15

Respuestas

  • Este problema se conoce por lo general como "saldo corriente" o "running total". Hasta la version 2008 R2, no hay una forma facil de hacerlo, y que tenga buen desempenio. Hay quienes recurren a usar cursor, query correlacionado, una union (join) de la tabla consigo misma, o una funcion de agregacion usando SQLCLR. En la version 2012, que ya esta por salir, tendremos un mejor soporte para este tipo de calculos.

    Es importante poder ordenar las filas en orden cronologico, para saber que transaccion ocurrio primero. Supongamos que tenemos una columna que nos de el oreden, ya sea el # de la transaccion o la fecha y hora en la que esta ocurrio.

    NUM_TRANS ITEM --- ARTICULO --- TIPOMOV --- CANTIDAD  ------<SALDO>
    1                  1236    CAMISA        01-INGRESO      20              20
    2                  1236    CAMISA        01-INGRESO      10              30
    3                  1236    CAMISA        02-SALIDA        5              25
    4                  1236    CAMISA        01-INGRESO      15              40
    5                  1236    CAMISA        02-SALIDA       10              30

    -- query correlacionado
    select
        A.ITEM,
        A.ARTICULO,
        A.TIPOMOV,
        A. CANTIDAD,
        (
        select sum(case when B.TIPO_MOV = '02-SALIDA' then -1 else 1 end * B.CANTIDAD)
        from T as B
        where B.ARTICULO = A.ARTICULO and B.NUM_TRANS <= A.NUM_TRANS
        ) AS SALDO
    from
        T as A
    order by
        A.NUM_TRANS;

     


    AMB

    Some guidelines for posting questions...

    jueves, 26 de enero de 2012 20:59

Todas las respuestas

  • Si ya la aplicación tiene buen tiempo de implementación, lo que tendias que hacer es unir las tablas que generan movimiento de los productos, como por ejemplo.

    Compras, Ventas, Transferencias (o cambio de bodega), Ajustes a Inventario. y haces una consulta a estas tres o cuatro tablas según sea el caso y la ordenas por fecha para que aparesca ordenado y la consulta del saldo pues vendria a ser una rutina para verificar si el registro anterior es ingreso entonces sumar caso contrario restar. por lo menos así lo enfrentaria yo.

    pero.... como ya dias vengo con este tipo de sistemas, lo que hice fue crear una tabla para generar un Tracking, un Trigger en las tablas necesarias para que cuando se inserte un registro se inserte automaticamente en la tabla "Tracking" indicando el tipo de movimiento, asi, evito unir varias tablas, solo me voy a una sola tabla a hacer la consulta.

    ademas, si se anula una factura o se devuelve el producto, igual genero un registro indicando porque entro el producto cuyo caso seria anulacion o devolución.

    analisalo por si aun estas a tiempo de implementar una tabla de Tracking de productos.

    Salu2,

     

     


    Marvin E. Pineda

      ComboBoxMultiColumns

     NetBarControl

      TextEditor

    jueves, 26 de enero de 2012 19:40
    Moderador
  • Estimado.

    Es para un reporte especifico , no se tiene acceso a otras partes del sistema y controlarlo de la manera que indicas.

    Se necesita resolver la consulta del modo indicado en mi post.

    De todas maneras gracias.

    saludos


    Rolando Lau Project Management
    jueves, 26 de enero de 2012 19:53
  • Este problema se conoce por lo general como "saldo corriente" o "running total". Hasta la version 2008 R2, no hay una forma facil de hacerlo, y que tenga buen desempenio. Hay quienes recurren a usar cursor, query correlacionado, una union (join) de la tabla consigo misma, o una funcion de agregacion usando SQLCLR. En la version 2012, que ya esta por salir, tendremos un mejor soporte para este tipo de calculos.

    Es importante poder ordenar las filas en orden cronologico, para saber que transaccion ocurrio primero. Supongamos que tenemos una columna que nos de el oreden, ya sea el # de la transaccion o la fecha y hora en la que esta ocurrio.

    NUM_TRANS ITEM --- ARTICULO --- TIPOMOV --- CANTIDAD  ------<SALDO>
    1                  1236    CAMISA        01-INGRESO      20              20
    2                  1236    CAMISA        01-INGRESO      10              30
    3                  1236    CAMISA        02-SALIDA        5              25
    4                  1236    CAMISA        01-INGRESO      15              40
    5                  1236    CAMISA        02-SALIDA       10              30

    -- query correlacionado
    select
        A.ITEM,
        A.ARTICULO,
        A.TIPOMOV,
        A. CANTIDAD,
        (
        select sum(case when B.TIPO_MOV = '02-SALIDA' then -1 else 1 end * B.CANTIDAD)
        from T as B
        where B.ARTICULO = A.ARTICULO and B.NUM_TRANS <= A.NUM_TRANS
        ) AS SALDO
    from
        T as A
    order by
        A.NUM_TRANS;

     


    AMB

    Some guidelines for posting questions...

    jueves, 26 de enero de 2012 20:59
  • Estimado Muchas Gracias por el codigo ,

    Funciona muy bien.

    Por lo que mencionas , este codigo no funcionara en SQL 2000 ???

    Es para ejecutarse en un sistema antiguo.

     

    saludos.

     


    Rolando Lau Project Management
    jueves, 26 de enero de 2012 22:10
  • Prueba esto, las salidas guardalas o mejor dicho las cantidades guardalas con cantidades negativas asi es mas facil calcular tu stock

    NUM_TRANS ITEM --- ARTICULO --- TIPOMOV --- CANTIDAD ------<SALDO>
    1 1236 CAMISA 01-INGRESO 20 20
    2 1236 CAMISA 01-INGRESO 10 30
    3 1236 CAMISA 02-SALIDA 5 -25
    4 1236 CAMISA 01-INGRESO  15 40
    5 1236 CAMISA 02-SALIDA   -10 30

    select
    A.ITEM,
    A.ARTICULO,
    A.TIPOMOV,
    A. CANTIDAD,

    ISNULL
    (
    select sum(B.CANTIDAD)
    from T as B
    where B.ARTICULO = A.ARTICULO and B.NUM_TRANS <= A.NUM_TRANS),0) AS SALDO
    from
    T as A

    order by
    A.NUM_TRANS;

      

    Capacitaciones Corporativas
    Capacitaciones Corporativas
    viernes, 27 de enero de 2012 4:37
  • Hola.

    El código sugerido Alejandro sí funciona en SQL Server 2000.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande

    viernes, 27 de enero de 2012 7:55
    Moderador
  • Hola Hunchback

    Tengo una aplicacion que se ha truncado hace dos semans por este tema.  El bendito problema que parece sencillo "SELECT SQL PARA SALDO DE KARDEX" no puedo solucionarlo (bueno, soy recien iniciado en el tema de visulBasic). Mi problema es muy semejante a tu ejemplo pero incluye LOTES además de ITEMS (que en mi caso son COD_ARTIC). Por favor, Hunchback liberame de este "problemilla" que ya me va a dejar calvo . . . .Mi tabla (access 2007 ) tiene entre otros campos lo sgte:

    id - cod_art - articulo -  LOTE - tipo_mov -  cant - saldo

    lo que busco es una consulta sql que me de el saldo de cada lote de un articulo a una fecha determinada (cod_art y fecha se establecen desde un formulario de ingreso de datos) y cada lote tiene un solo movimiento de ENTrada y varios movimientos de SALida.

    la sgte 'sql' (A) lista muy bien los lotes y sus cantidades de ENTRADA

    sql = "SELECT A.LOTE,  A.CANT " FROM KARDEX AS A  WHERE A.COD_ART LIKE '" & codArt & "' AND A.F_DOC <=  #" & fDoc & "# AND A.TIPO_MOV ='ENT' GROUP BY A.LOTE, A.CANT"

    la sgte 'sql' (B) lista los LOTEs  y sus cantidades de SALIDA (los muestro en negativo)

    sql = "SELECT B.LOTE, SUM(B.CANT*-1) AS CANT  FROM KARDEX AS B WHERE B.COD_ART LIKE '" & codArt & "' AND B.F_DOC <=  #" & fDoc & "#  AND B.TIPO_MOV ='SAL' GROUP BY B.LOTE"

    pero cuando intento incluir la subconsulta B en A aparece el problema:

    sql = "SELECT A.LOTE, A.CANT, (SELECT SUM(B.CANT*-1)  FROM KARDEX AS B " & _
                                       "WHERE B.TIPO_MOV ='SAL' AND B.ID <= A.ID ) AS SALDO " & _
                  "FROM KARDEX AS A  WHERE A.COD_ART LIKE '" & codArt & "' AND A.F_DOC <=  #" & fDoc & "#  AND A.TIPO_MOV ='ENT' GROUP BY A.LOTE, A.CANT"

    De antemano . . .Gracias . . .  TOTALES!! omenachor-hotmail.com  omenacho-gmail.com

    SLDS dsd LIMA - PERU

    martes, 5 de febrero de 2013 0:56
  • Hola aunque este post es viejo, quiero reactivarlo porque estoy presentando problemas con este tema o parecido.

    Tengo que realizar algo parecido a lo que se pidió al principio, copié el código y pude obtener un resultado; pero no como yo deseo. Yo tengo SQL 2008 R2. Les pongo como me sale a mi...

    NUM_TRANS ITEM --- ARTICULO --- TIPOMOV --- CANTIDAD  ------<SALDO>
    1                  1236    CAMISA        01-INGRESO      20              30
    2                  1236    CAMISA        01-INGRESO      10              30
    3                  1236    CAMISA        02-SALIDA        5              30
    4                  1236    CAMISA        01-INGRESO      15             30
    5                  1236    CAMISA        02-SALIDA       10              30

    Yo hago lo siguiente:

    -----------------------------------------------------------------------------------------

    select
        a.codigo_asiento,
        a.fecha,
        a.Origen,
        a.Nro_Obj,
        a.NroDoc,
        a.Doc,
        a.detalle,
        a.monto_debe,
        a.monto_haber,
        (
        select
            sum(
                CASE
                    when b.tipo_movimiento = 'SALIDA' then -1
                    else 1
                END
                * b.monto_total
            )
        from #mayor as b ) as Saldo
    from #MAYOR AS a order by fecha

    -----------------------------------------------------------------------------------------

    O sea solo me está poniendo en la columna Saldo el resultado final. Y yo deseo lo que está pidiendo el que inició el Post. Como puedo lograr que en cada fila se vayan viendo las sumas o restas de forma incremental??

    Saludos,

    David

    viernes, 21 de febrero de 2014 13:20
  • El sub-query debe estar correlacionado con el query externo o de lo contrario obtendras el mismo resultado para todas las filas. Supongamos que el numero de la transaccion indica la ocurrencia cronologica de la transaccion entonces tendras que correlacionar el sub-query por el tipo de producto y el numero de la transaccion. En tu caso no se cual es la columna que indica la ocurrencia cronologica de la transaccion y que columnas usar para el producto, etc.

    AMB

    Some guidelines for posting questions...


    domingo, 23 de febrero de 2014 19:53
  • Muy bueno muy bueno

    Conocuica

    sábado, 3 de mayo de 2014 18:46
  • Muy buena la respuesta, lo aplique, nada mas que tengo una pregunta quisiera que me ayuden.. El problema es que cuando un producto no tiene movimiento en un mes, no lista, a pesar de tener saldo del mes pasado, como puede solucionar esto.

    01-08-18  Entrada 20 Saldo 20
    10-08-18 Salida 5       Saldo 15
    --------------------------------------------
    setiembre sin movimiento, pero tiene saldo anterior (a agosto) : 15 (esto no sale
    --------------------------------------------
    octubre
    01-10-18 Entrada 20 Saldo 35
    15-10-18 Salida 5      Saldo 30
    -------------------------------------------

    Como resuelvo que en setiembre me salga por lo menos el saldo

    - le inserto una linea con campos en null (como ?)

    Agradecere su apoyo

    Armando


    Armando

    jueves, 1 de noviembre de 2018 4:49