none
saldo acumulado consulta sql RRS feed

  • Pregunta

  • Hola gente estoy tratando de hacer que la consulta me devuelva los movimientos de venta dentro de un periodo pero me interesa saber el saldo acumulado hasta antes de ese periodo, es decir si el usuario quiere consultar por el 1 de junio hasta el 2 de agosto que la consulta empiece con el saldo inicial que tenia hasta el 1 de junio no se si me explico

    Tengo el siguiente SP:

     ;with cte 
     as
     (select DetallesComprobanteVenta.idComprobanteVenta,
     sum( case 
    		when ComprobantesVenta.idTipoComprobante=1 or ComprobantesVenta.idTipoComprobante=3
    		then cantidad*precio* (1-(isnull(descuento,0)/100)) *(1+iva/100)
    		else 0
    	  end) as DEBE,
     sum( case
    		 when ComprobantesVenta.idTipoComprobante=2
    		 then cantidad*precio*(1-(isnull(descuento,0)/100))*(1+iva/100)
    		 else 0
    	  end) as HABER, 
      from DetallesComprobanteVenta 
     inner join ComprobantesVenta on DetallesComprobanteVenta.idComprobanteVenta=ComprobantesVenta.idComprobanteVenta
     inner join Productos on DetallesComprobanteVenta.idProducto =Productos.idProducto
     where ComprobantesVenta.idCliente=@idCliente and ComprobantesVenta.fechaEmision>@fechaInicio and ComprobantesVenta.fechaEmision<@fechaFin
     group by DetallesComprobanteVenta.idComprobanteVenta
     )
     select ComprobantesVenta.idComprobanteVenta,TiposComprobanteVenta.nombre,ComprobantesVenta.letraComprobante,numComprobante,fechaEmision,DEBE,HABER
     from ComprobantesVenta 
     inner join TiposComprobanteVenta on ComprobantesVenta.idTipoComprobante=TiposComprobanteVenta.idTipoComprobante
     inner join cte on cte.idComprobanteVenta=ComprobantesVenta.idComprobanteVenta

    La consulta devuelve lo siguiente:


    La columna saldo la calculaba luego desde c# pero ahora me surge esto de poder arrancar con un saldo inicial desde antes del periodo seleccionado por el usuario. Hay alguna forma de calcular el saldo inicial y hacer el acumulado en la misma consulta? o directamente hago otra consulta a parte para obtener el saldo inicial??

    que recomiendan?

    saludos

    martes, 27 de agosto de 2019 19:14

Respuestas

  • Hola Artemis Spectrum:

    ¿Cual es la salida deseada? 

    Esta es una posible, solución, pero tienes que matizar un poco más, lo que para tí significa saldo inicial para cada una de las filas, por numero de documento, y lo que significa saldo acumulado.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    WITH s1
         AS (
    	SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta),
         s2
         AS (SELECT ISNULL(haber, 0) - ISNULL(debe, 0) AS saldo, 
                    idComprobanteVenta
             FROM s1),
         cte
         AS (SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision > @fechaInicio
                   AND ComprobantesVenta.fechaEmision < @fechaFin
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta)
         SELECT ComprobantesVenta.idComprobanteVenta, 
                TiposComprobanteVenta.nombre, 
                ComprobantesVenta.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER,
    		  S2.saldo
         FROM ComprobantesVenta
              INNER JOIN TiposComprobanteVenta ON ComprobantesVenta.idTipoComprobante = TiposComprobanteVenta.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
    		LEFT JOIN S2 ON CTE.idComprobanteVenta = S2.idComprobanteVenta;

    martes, 27 de agosto de 2019 21:01
  • Hola Artemis Spectrum:

    con saldo inicial me refiero a la deuda acumulada que tengo anterior a la fecha de inicio

    Por tanto Saldo es un único valor.

    La opción menos costosa en procesamiento, y más lógica, es preguntar en una consulta el saldo. Y en otra, lo que tienes, y hacer las operaciones en capa cliente.


    miércoles, 28 de agosto de 2019 3:30

Todas las respuestas

  • Hola Artemis Spectrum:

    ¿Cual es la salida deseada? 

    Esta es una posible, solución, pero tienes que matizar un poco más, lo que para tí significa saldo inicial para cada una de las filas, por numero de documento, y lo que significa saldo acumulado.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    WITH s1
         AS (
    	SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta),
         s2
         AS (SELECT ISNULL(haber, 0) - ISNULL(debe, 0) AS saldo, 
                    idComprobanteVenta
             FROM s1),
         cte
         AS (SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision > @fechaInicio
                   AND ComprobantesVenta.fechaEmision < @fechaFin
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta)
         SELECT ComprobantesVenta.idComprobanteVenta, 
                TiposComprobanteVenta.nombre, 
                ComprobantesVenta.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER,
    		  S2.saldo
         FROM ComprobantesVenta
              INNER JOIN TiposComprobanteVenta ON ComprobantesVenta.idTipoComprobante = TiposComprobanteVenta.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
    		LEFT JOIN S2 ON CTE.idComprobanteVenta = S2.idComprobanteVenta;

    martes, 27 de agosto de 2019 21:01
  • Hola Artemis Spectrum:

    ¿Cual es la salida deseada? 

    Esta es una posible, solución, pero tienes que matizar un poco más, lo que para tí significa saldo inicial para cada una de las filas, por numero de documento, y lo que significa saldo acumulado.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    WITH s1
         AS (
    	SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta),
         s2
         AS (SELECT ISNULL(haber, 0) - ISNULL(debe, 0) AS saldo, 
                    idComprobanteVenta
             FROM s1),
         cte
         AS (SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision > @fechaInicio
                   AND ComprobantesVenta.fechaEmision < @fechaFin
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta)
         SELECT ComprobantesVenta.idComprobanteVenta, 
                TiposComprobanteVenta.nombre, 
                ComprobantesVenta.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER,
    		  S2.saldo
         FROM ComprobantesVenta
              INNER JOIN TiposComprobanteVenta ON ComprobantesVenta.idTipoComprobante = TiposComprobanteVenta.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
    		LEFT JOIN S2 ON CTE.idComprobanteVenta = S2.idComprobanteVenta;

    con saldo inicial me refiero a la deuda acumulada que tengo anterior a la fecha de inicio

    la idea seria tener en cuenta las deudas anteriores para empezar a calcular el saldo entre dos fechas teniendo en cuenta la deuda anterior. El acumulado seria que a partir de la resuta DEBE-HABER se va generando el saldo pero siempre la fila siguiente le tiene que ir restando al saldo anterior y asi sucesivamente.. no se si me logré expresar.

    PD: probé el código que me pasaste pero me devuelve NULL en todas las columnas de saldo

    martes, 27 de agosto de 2019 21:30
  • Hola Artemis Spectrum:

    con saldo inicial me refiero a la deuda acumulada que tengo anterior a la fecha de inicio

    Por tanto Saldo es un único valor.

    La opción menos costosa en procesamiento, y más lógica, es preguntar en una consulta el saldo. Y en otra, lo que tienes, y hacer las operaciones en capa cliente.


    miércoles, 28 de agosto de 2019 3:30
  • Hola Artemis Spectrum:

    con saldo inicial me refiero a la deuda acumulada que tengo anterior a la fecha de inicio

    Por tanto Saldo es un único valor.

    La opción menos costosa en procesamiento, y más lógica, es preguntar en una consulta el saldo. Y en otra, lo que tienes, y hacer las operaciones en capa cliente.


    claro la menos complicada creo que seria esa, hacerla en una consulta a parte y obtener el saldo anterior luego con eso operar en capa de aplicación. Yo consultaba acá por si habia algo más óptimo haciendolo en una sola consulta, pero si no queda otra lo hago en dos consultas separadas y me ahorro tanto problema
    miércoles, 28 de agosto de 2019 4:02
  • Hola Artemis Spectrum:

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    WITH s1
         AS (
    	SELECT ComprobantesVenta.numComprobante, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY ComprobantesVenta.numComprobante),
         s2
         AS (SELECT ISNULL(haber, 0) - ISNULL(debe, 0) AS saldo, 
                    numcomprobante
             FROM s1),
         cte
         AS (SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision > @fechaInicio
                   AND ComprobantesVenta.fechaEmision < @fechaFin
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta)
         SELECT ComprobantesVenta.idComprobanteVenta, 
                TiposComprobanteVenta.nombre, 
                ComprobantesVenta.letraComprobante, 
                ComprobantesVenta.numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER,
    		  S2.saldo
    		 
         FROM ComprobantesVenta
              INNER JOIN TiposComprobanteVenta ON ComprobantesVenta.idTipoComprobante = TiposComprobanteVenta.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
    		LEFT JOIN S2 ON ComprobantesVenta.numComprobante = S2.numComprobante;
    La relación del conjunto s1 con los comprobantes no es por el idComprobante, sino por el numComprobante.


    miércoles, 28 de agosto de 2019 4:19
  • Hola Artemis Spectrum:

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    WITH s1
         AS (
    	SELECT ComprobantesVenta.numComprobante, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY ComprobantesVenta.numComprobante),
         s2
         AS (SELECT ISNULL(haber, 0) - ISNULL(debe, 0) AS saldo, 
                    numcomprobante
             FROM s1),
         cte
         AS (SELECT DetallesComprobanteVenta.idComprobanteVenta, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision > @fechaInicio
                   AND ComprobantesVenta.fechaEmision < @fechaFin
             GROUP BY DetallesComprobanteVenta.idComprobanteVenta)
         SELECT ComprobantesVenta.idComprobanteVenta, 
                TiposComprobanteVenta.nombre, 
                ComprobantesVenta.letraComprobante, 
                ComprobantesVenta.numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER,
    		  S2.saldo
    		 
         FROM ComprobantesVenta
              INNER JOIN TiposComprobanteVenta ON ComprobantesVenta.idTipoComprobante = TiposComprobanteVenta.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
    		LEFT JOIN S2 ON ComprobantesVenta.numComprobante = S2.numComprobante;
    La relación del conjunto s1 con los comprobantes no es por el idComprobante, sino por el numComprobante.


    intenté con ese código pero sigue devolviendo NULL en las columnas de saldo

    se me ocurre llamar dos veces al procedimiento y en el primer llamado calcular el saldo anterior

    pasando los parametros fechafin como la fechaInicio del intervalo a consultar, entonces en base a este procedimiento obtengo todos los movimientos del DEBE Y HABER luego haciendo calculos obtengo ese saldo inicial y llamo al otro procedimiento donde opero con los DEBE y HABER a partir del saldo acumulado en el anterior llamado.

    Este planteo puede ser válido/óptimo??



    miércoles, 28 de agosto de 2019 4:23
  • Tienes algún registro anterior a la fecha de inicio? para esos documentos, para ese cliente.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    
    
    	SELECT ComprobantesVenta.numComprobante, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY ComprobantesVenta.numComprobante
    ¿Cuál es la salida?


    miércoles, 28 de agosto de 2019 4:29
  • Tienes algún registro anterior a la fecha de inicio? para esos documentos, para ese cliente.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20190825 14:00';
    DECLARE @fechaFin DATETIME= '20191201';
    
    
    	SELECT ComprobantesVenta.numComprobante, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 1
                                 OR ComprobantesVenta.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN ComprobantesVenta.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta
                  INNER JOIN ComprobantesVenta ON DetallesComprobanteVenta.idComprobanteVenta = ComprobantesVenta.idComprobanteVenta
                  INNER JOIN Productos ON DetallesComprobanteVenta.idProducto = Productos.idProducto
             WHERE ComprobantesVenta.idCliente = @idCliente
                   AND ComprobantesVenta.fechaEmision <= @fechaInicio
             GROUP BY ComprobantesVenta.numComprobante
    ¿Cuál es la salida?


    ahi me anduvo, no entiendo porque lo haces con numcomprobante a los join y no con los ids??
    miércoles, 28 de agosto de 2019 4:33
  • En una de las preguntas anteriores, comentamos que el saldo era un valor único. 

    Es único, por numComprobante, si fuera por idMovimiento, no existiría un saldo anterior, porque el movimiento se crea en una fecha.

    Si embargo, si es por numComprobante, antes del 1 de enero puedes tener un factura que genera un saldo, y a posteriori tienes varios movimientos que ponen datos en el debe o haber, pero lo que los enlaza no es el id, pues son diferentes.

    ¿Cual es el saldo. el id5, o el id6 o el id7, o la suma de todos los movimientos para numComprobante, cuya fecha sea anterior a yyyyMMdd?

    miércoles, 28 de agosto de 2019 4:44
  • En una de las preguntas anteriores, comentamos que el saldo era un valor único. 

    Es único, por numComprobante, si fuera por idMovimiento, no existiría un saldo anterior, porque el movimiento se crea en una fecha.

    Si embargo, si es por numComprobante, antes del 1 de enero puedes tener un factura que genera un saldo, y a posteriori tienes varios movimientos que ponen datos en el debe o haber, pero lo que los enlaza no es el id, pues son diferentes.

    ¿Cual es el saldo. el id5, o el id6 o el id7, o la suma de todos los movimientos para numComprobante, cuya fecha sea anterior a yyyyMMdd?


    No entiendo por qué se enlazan con número de comprobante si este es distinto cada vez que se ingresa un comprobante de venta al igual que pasa con el id que es autoincremental, es decir el numero de comprobante si yo emito una factura me la va a hacer con la siguiente numeración, cada numeración es independiente según el tipo de comprobante es decir yo hago la factura 10 pero si voy a emitir una nota de credito su numeración podría ser la numero 4 (siempre verificando la numeración de la ultima nota de crédito emitida)
    miércoles, 28 de agosto de 2019 5:19
  • Hola Artemis.

    Pon un ejemplo explicito de las filas con saldo y acumulados incluidos que deseas obtener

    miércoles, 28 de agosto de 2019 8:47
  • Hola Artemis.

    Pon un ejemplo explicito de las filas con saldo y acumulados incluidos que deseas obtener

    Adjunto un ejemplo en excel:

    Por ejemplo lo que quiero es si hace una consulta de la cuenta corriente con fecha de inicio posterior al 2/8/2018 que el saldo comience a acumularse tomando en cuenta la deuda anterior, es decir que arranca con un saldo inicial de 2700

    miércoles, 28 de agosto de 2019 11:01
  • Eso no es problema.

    Entiendo entonces que es una cuenta corriente por cliente??? 

    miércoles, 28 de agosto de 2019 15:13
  • Eso no es problema.

    Entiendo entonces que es una cuenta corriente por cliente??? 

    claro es una cuenta corriente por cliente que se puede consultar entre fechas
    miércoles, 28 de agosto de 2019 15:14
  • Ok. De noche le pego una vuelta, y te doy la solución.
    miércoles, 28 de agosto de 2019 16:15
  • Hola Artemis Spectrum:

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20180802';
    DECLARE @fechaFin DATETIME= '20201201';
    WITH s1
         AS (SELECT c.idCliente, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision < @fechaInicio
             GROUP BY c.idCliente),
         s2
         AS (SELECT ISNULL(DEBE, 0) - ISNULL(HABER, 0) AS saldo, 
                    idCliente
             FROM s1),
         cte
         AS (SELECT d.idComprobanteVenta, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
                  INNER JOIN Productos ON d.idProducto = Productos.idProducto
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision >= @fechaInicio
                   AND c.fechaEmision <= @fechaFin
             GROUP BY d.idComprobanteVenta)
         SELECT c.idComprobanteVenta, 
                t.nombre, 
                c.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER, 
                SALDO + SUM(DEBE - HABER) OVER(PARTITION BY C.IDCLIENTE
                ORDER BY FECHAEMISION DESC, 
                         numComprobante ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS SALDO
         FROM ComprobantesVenta c
              INNER JOIN TiposComprobanteVenta t ON c.idTipoComprobante = t.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = c.idComprobanteVenta
              LEFT JOIN S2 ON c.idCliente = S2.idCliente;

    Salida

    La linea 1 no sale porque esta fuera del filtro.


    jueves, 29 de agosto de 2019 4:24
  • Hola Artemis Spectrum:

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20180802';
    DECLARE @fechaFin DATETIME= '20201201';
    WITH s1
         AS (SELECT c.idCliente, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision < @fechaInicio
             GROUP BY c.idCliente),
         s2
         AS (SELECT ISNULL(DEBE, 0) - ISNULL(HABER, 0) AS saldo, 
                    idCliente
             FROM s1),
         cte
         AS (SELECT d.idComprobanteVenta, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
                  INNER JOIN Productos ON d.idProducto = Productos.idProducto
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision >= @fechaInicio
                   AND c.fechaEmision <= @fechaFin
             GROUP BY d.idComprobanteVenta)
         SELECT c.idComprobanteVenta, 
                t.nombre, 
                c.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER, 
                SALDO + SUM(DEBE - HABER) OVER(PARTITION BY C.IDCLIENTE
                ORDER BY FECHAEMISION DESC, 
                         numComprobante ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS SALDO
         FROM ComprobantesVenta c
              INNER JOIN TiposComprobanteVenta t ON c.idTipoComprobante = t.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = c.idComprobanteVenta
              LEFT JOIN S2 ON c.idCliente = S2.idCliente;

    Salida

    La linea 1 no sale porque esta fuera del filtro.


    Lo estuve probando pero no me funciona. En este caso el cliente solo tiene esos dos movimientos (no hay anteriores a la fecha de inicio) y el saldo me lo devuelve como NULO. Pero si tomo a partir del 26/8 me devuelve solamente 1 registro y contabilizando la deuda anterior. Esto estaría bien pero no se porque no funciona abarcando desde el primer movimiento


    jueves, 29 de agosto de 2019 5:13
  • Hola Artemis Spectrum:

    Porque si no hay registros, saldo es null y null + lo que sea = null

    Vamos a protegernos.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20180802';
    DECLARE @fechaFin DATETIME= '20201201';
    WITH s1
         AS (
      SELECT c.idCliente, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision < @fechaInicio
             GROUP BY c.idCliente),
         s2
         AS (SELECT ISNULL(DEBE, 0) - ISNULL(HABER, 0) AS saldo, 
                    idCliente
             FROM s1),
         cte
         AS (SELECT d.idComprobanteVenta, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
                  INNER JOIN Productos ON d.idProducto = Productos.idProducto
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision >= @fechaInicio
                   AND c.fechaEmision <= @fechaFin
             GROUP BY d.idComprobanteVenta)
         SELECT c.idComprobanteVenta, 
                t.nombre, 
                c.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER, 
                isnull(SALDO,0) + SUM(DEBE - HABER) OVER(PARTITION BY C.IDCLIENTE
                ORDER BY FECHAEMISION DESC, 
                         numComprobante ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS SALDO
         FROM ComprobantesVenta c
              INNER JOIN TiposComprobanteVenta t ON c.idTipoComprobante = t.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = c.idComprobanteVenta
              LEFT JOIN S2 ON c.idCliente = S2.idCliente;

    Observa, que sólo cambia ISNULL(SALDO,0) + SUM(DEBE - HABER)......

    jueves, 29 de agosto de 2019 20:29
  • Hola Artemis Spectrum:

    Porque si no hay registros, saldo es null y null + lo que sea = null

    Vamos a protegernos.

    DECLARE @idcliente INT= 1;
    DECLARE @fechaInicio DATETIME= '20180802';
    DECLARE @fechaFin DATETIME= '20201201';
    WITH s1
         AS (
      SELECT c.idCliente, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision < @fechaInicio
             GROUP BY c.idCliente),
         s2
         AS (SELECT ISNULL(DEBE, 0) - ISNULL(HABER, 0) AS saldo, 
                    idCliente
             FROM s1),
         cte
         AS (SELECT d.idComprobanteVenta, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 1
                                 OR c.idTipoComprobante = 3
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS DEBE, 
                    SUM(CASE
                            WHEN c.idTipoComprobante = 2
                            THEN cantidad * precio * (1 - (ISNULL(descuento, 0) / 100)) * (1 + iva / 100)
                            ELSE 0
                        END) AS HABER
             FROM DetallesComprobanteVenta d
                  INNER JOIN ComprobantesVenta c ON d.idComprobanteVenta = c.idComprobanteVenta
                  INNER JOIN Productos ON d.idProducto = Productos.idProducto
             WHERE c.idCliente = @idCliente
                   AND c.fechaEmision >= @fechaInicio
                   AND c.fechaEmision <= @fechaFin
             GROUP BY d.idComprobanteVenta)
         SELECT c.idComprobanteVenta, 
                t.nombre, 
                c.letraComprobante, 
                numComprobante, 
                fechaEmision, 
                DEBE, 
                HABER, 
                isnull(SALDO,0) + SUM(DEBE - HABER) OVER(PARTITION BY C.IDCLIENTE
                ORDER BY FECHAEMISION DESC, 
                         numComprobante ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS SALDO
         FROM ComprobantesVenta c
              INNER JOIN TiposComprobanteVenta t ON c.idTipoComprobante = t.idTipoComprobante
              INNER JOIN cte ON cte.idComprobanteVenta = c.idComprobanteVenta
              LEFT JOIN S2 ON c.idCliente = S2.idCliente;

    Observa, que sólo cambia ISNULL(SALDO,0) + SUM(DEBE - HABER)......

    yo habia intentado hacer esto pero no me dejaba entonces desistí de probarlo jaja
     isnull(SALDO+ SUM(DEBE - HABER),0)


    jueves, 29 de agosto de 2019 21:19