none
Acumular saldo RRS feed

  • Pregunta

  • Hola!

    Estoy iniciándome en SQL y necesito actualizar una tabla acumulando valores en un campo.

    Tengo el siguiente código pero estoy perdido a la hora de actualizar el campo SALDO. Hay que notar tambien que parto de un valor tomado de otra tabla.

    ¿podéis darme alguna orientación? 

    MUY AGRADECIDO !!

    IF object_id('dbo.tmpLineas_22') IS NOT NULL BEGIN DROP TABLE dbo.tmpLineas_22 END CREATE TABLE tmpLineas_22( Id int NOT NULL IDENTITY, Origen varchar(4), Fecha_Op date, Fecha_Va date, Concepto_C varchar(2), Concepto_P varchar(3), Importe float, Saldo float, Documento varchar(10), Ref_1 varchar(12), Ref_2 varchar(16), CC varchar(20) ); INSERT INTO [dbo].[tmpLineas_22]( Origen, Fecha_Op, Fecha_Va, Concepto_C, Concepto_P, Importe, Saldo, Documento, Ref_1, Ref_2, CC) SELECT SUBSTRING(campo,7,4), CONVERT(DATETIME, SUBSTRING(campo,15,2)+'/'+SUBSTRING(campo,13,2)+'/'+SUBSTRING(campo,11,2)), CONVERT(DATETIME, SUBSTRING(campo,21,2)+'/'+SUBSTRING(campo,19,2)+'/'+SUBSTRING(campo,17,2)), SUBSTRING(campo,23,2), SUBSTRING(campo,25,3), CASE WHEN SUBSTRING(campo,28,1)='1' THEN (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100)*-1 ELSE (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100) END,

    /*

    Aquí iría el SALDO, resultado acumular a una variable @Saldo la cantidad inicial tomada de otra tabla:

    DECLARE @SaldoTemporal float SELECT @SaldoTemporal = Saldo_ini from tmpCabecera_11

    */ SUBSTRING(campo,43,10), SUBSTRING(campo,53,12), SUBSTRING(campo,65,16), (SELECT cc FROM tmpCabecera_11) FROM [dbo].[C43tmp] WHERE SUBSTRING(campo,1,2)='22' DECLARE @SaldoTemporal float SELECT @SaldoTemporal = Saldo_ini from tmpCabecera_11 UPDATE tmpLineas_22 SET Saldo = @SaldoTemporal, @SaldoTemporal = @SaldoTemporal + Saldo




    • Editado R_Jorge martes, 8 de agosto de 2017 18:16
    • Tipo cambiado Moderador M miércoles, 16 de agosto de 2017 18:36
    • Tipo cambiado Moderador M miércoles, 23 de agosto de 2017 17:08
    martes, 8 de agosto de 2017 18:14

Respuestas

  • Bueno al final concluyo con una solución de 'andar por casa' porque mis conocimientos no dan para más, pero agradecería que alguien me diera una solución más elegante que seguro que la hay.

    Por lo pronto esto funciona:

    IF object_id('dbo.tmpLineas_22') IS NOT NULL BEGIN DROP TABLE dbo.tmpLineas_22 END CREATE TABLE tmpLineas_22( Id int NOT NULL IDENTITY, Origen varchar(4), Fecha_Op date, Fecha_Va date, Concepto_C varchar(2), Concepto_P varchar(3), --Signo varchar(1), Importe float, Saldo float, Documento varchar(10), Ref_1 varchar(12), Ref_2 varchar(16), CC varchar(20) ); INSERT INTO [dbo].[tmpLineas_22]( Origen, Fecha_Op, Fecha_Va, Concepto_C, Concepto_P, --Signo, Importe, Saldo, Documento, Ref_1, Ref_2, CC) SELECT SUBSTRING(campo,7,4), CONVERT(DATETIME, SUBSTRING(campo,15,2)+'/'+SUBSTRING(campo,13,2)+'/'+SUBSTRING(campo,11,2)), CONVERT(DATETIME, SUBSTRING(campo,21,2)+'/'+SUBSTRING(campo,19,2)+'/'+SUBSTRING(campo,17,2)), SUBSTRING(campo,23,2), CASE WHEN SUBSTRING(campo,28,1)='1' THEN (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100)*-1 ELSE (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100) END,

    -- Saldo 0, SUBSTRING(campo,43,10), SUBSTRING(campo,53,12), SUBSTRING(campo,65,16), (SELECT cc FROM tmpCabecera_11) FROM [dbo].[C43tmp] WHERE SUBSTRING(campo,1,2)='22' -- Actualizamos el saldo de la tabla tmpLineas_22 valiéndonos de una tabla temporal CREATE TABLE temp(id INT, importe FLOAT, acumulado FLOAT) INSERT INTO temp(id, importe, acumulado) SELECT a.id, a.importe, sum(b.importe) as acumulado FROM tmpLineas_22 AS a LEFT JOIN tmpLineas_22 AS b ON a.id >= b.Id GROUP BY a.id, a.Importe ORDER BY a.id UPDATE tmpLineas_22 SET Saldo = (SELECT acumulado FROM temp WHERE tmpLineas_22.Id=temp.id) DROP TABLE temp

    Hice la exportación en dos pasos, en el primero dejé el saldo a 0 y en el segundo creé una tabla temporal donde hago el propio cálculo que luego actualizo en la tabla principal.


    • Editado R_Jorge miércoles, 9 de agosto de 2017 6:50
    • Marcado como respuesta Moderador M miércoles, 23 de agosto de 2017 17:08
    miércoles, 9 de agosto de 2017 6:49

Todas las respuestas

  • Cual version de SQL Server usas?

    Si el saldo se refiere al total corriente a partir de un saldo inicial al cual se la adiciona un valor de acuerdo a la fila corriente entonces deberiamos saber el orden de las filas para calcular el total corriente y que columna usar para la agregacion.

    Ejemplo:

    with R1 as (
    select Id, importe, row_number() over(order by fecha_op, Id) as rn
    from tmpLineas_22
    )
    , R2 as (
    select Id, sum(case when rn = 1 then @saldo_inicial else 0 end) + importe) over(order by rn rows unbounded preceding) as rt
    from R1
    )
    update R2 set saldo = rt;

    Claro esta que el saldo corriente pudiera depender del concepto, etc. pata lo cual deberas darnos la logica a seguir.


    AMB

    Some guidelines for posting questions...

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



    martes, 8 de agosto de 2017 18:37
  • Gracias por tu respuesta!

    Uso SQL Server 2014 Express Ed.

    La tabla que estoy transformando viene de un fichero plano que ya está ordenado de 'fábrica' y tan sólo habría que ir acumulando en la columna de 'Saldo' el valor de la columna 'Importe' teniendo en cuenta que el saldo inicial proviene de una segunda tabla (como ya indiqué el post).

    Intenté hacer un UPDATE después, con:

    DECLARE @SaldoTemporal float
    SELECT @SaldoTemporal = Saldo_ini from tmpCabecera_11
    
    UPDATE tmpLineas_22 SET Saldo = @SaldoTemporal, @SaldoTemporal = @SaldoTemporal + Saldo
    Pero con eso sólo conseguía que la columna saldo figurase siempre con el saldo inicial.


    martes, 8 de agosto de 2017 19:55
  • Rebuscando por ahí y haciendo alguna prueba he llegado a esto:

    Select a.id, a.importe, sum(b.importe) as acumulado
    from tmpLineas_22 as a
    left join
    tmpLineas_22 as b
    on  a.id >= b.Id
    group by a.id, a.Importe
    order by a.Id

    Lo que no sé es cómo hacer de ese bloque de código una consulta que inserte el valor 'escalar' del Saldo en la tabla resultado


    • Editado R_Jorge miércoles, 9 de agosto de 2017 6:18
    martes, 8 de agosto de 2017 20:36
  • Bueno al final concluyo con una solución de 'andar por casa' porque mis conocimientos no dan para más, pero agradecería que alguien me diera una solución más elegante que seguro que la hay.

    Por lo pronto esto funciona:

    IF object_id('dbo.tmpLineas_22') IS NOT NULL BEGIN DROP TABLE dbo.tmpLineas_22 END CREATE TABLE tmpLineas_22( Id int NOT NULL IDENTITY, Origen varchar(4), Fecha_Op date, Fecha_Va date, Concepto_C varchar(2), Concepto_P varchar(3), --Signo varchar(1), Importe float, Saldo float, Documento varchar(10), Ref_1 varchar(12), Ref_2 varchar(16), CC varchar(20) ); INSERT INTO [dbo].[tmpLineas_22]( Origen, Fecha_Op, Fecha_Va, Concepto_C, Concepto_P, --Signo, Importe, Saldo, Documento, Ref_1, Ref_2, CC) SELECT SUBSTRING(campo,7,4), CONVERT(DATETIME, SUBSTRING(campo,15,2)+'/'+SUBSTRING(campo,13,2)+'/'+SUBSTRING(campo,11,2)), CONVERT(DATETIME, SUBSTRING(campo,21,2)+'/'+SUBSTRING(campo,19,2)+'/'+SUBSTRING(campo,17,2)), SUBSTRING(campo,23,2), CASE WHEN SUBSTRING(campo,28,1)='1' THEN (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100)*-1 ELSE (CONVERT(FLOAT, SUBSTRING(campo,29,14))/100) END,

    -- Saldo 0, SUBSTRING(campo,43,10), SUBSTRING(campo,53,12), SUBSTRING(campo,65,16), (SELECT cc FROM tmpCabecera_11) FROM [dbo].[C43tmp] WHERE SUBSTRING(campo,1,2)='22' -- Actualizamos el saldo de la tabla tmpLineas_22 valiéndonos de una tabla temporal CREATE TABLE temp(id INT, importe FLOAT, acumulado FLOAT) INSERT INTO temp(id, importe, acumulado) SELECT a.id, a.importe, sum(b.importe) as acumulado FROM tmpLineas_22 AS a LEFT JOIN tmpLineas_22 AS b ON a.id >= b.Id GROUP BY a.id, a.Importe ORDER BY a.id UPDATE tmpLineas_22 SET Saldo = (SELECT acumulado FROM temp WHERE tmpLineas_22.Id=temp.id) DROP TABLE temp

    Hice la exportación en dos pasos, en el primero dejé el saldo a 0 y en el segundo creé una tabla temporal donde hago el propio cálculo que luego actualizo en la tabla principal.


    • Editado R_Jorge miércoles, 9 de agosto de 2017 6:50
    • Marcado como respuesta Moderador M miércoles, 23 de agosto de 2017 17:08
    miércoles, 9 de agosto de 2017 6:49