First, we put together an example like yours:
DECLARE @Tabla TABLE (
Id INT IDENTITY,
Nombres VARCHAR(255),
Attributos NUMERIC(15,2),
Altura NUMERIC(15,2),
Gtb NUMERIC(15,2)
)
INSERT INTO @Tabla (Nombres, Attributos, Altura)
VALUES ('Pedro*', 0.5, 5.1),
('Anna', 0.6, 4.3),
('Carla*', 0.3, 6.4),
('Johan*', 0.4, 3.4),
('Bryan', 10, 6),
('Cecilia*', 5, 5.7)
It is fundamental that the input table has a unique ID
for each row, in this case we simulate it with a Id INT IDENTITY
. The next thing is to create a temporary table where we will store the result of the accumulated sum, we need to do this to then update the final table:
DECLARE @TablaResultados TABLE (
Id INT,
Nombres VARCHAR(255),
Gtb NUMERIC(15,2)
)
Now we do a query to achieve the accumulated sum but only of certain records, this is an example, note that I am simply selecting those rows where Nombres
contain an asterisk, the actual filter you will configure it with what corresponds:
;
WITH CTE AS (
SELECT Id,
Nombres,
Attributos,
ROW_NUMBER() OVER (ORDER BY Id) RN
FROM @Tabla
WHERE CHARINDEX('*', Nombres) > 0
)
INSERT INTO @TablaResultados ( Id, Nombres, Gtb)
SELECT T1.Id,
T1.Nombres,
SUM(T2.Attributos) AS 'Gtb'
FROM CTE T1
LEFT JOIN CTE T2
ON T2.RN <= T1.RN
GROUP BY
T1.Id,
T1.Nombres
We use a "Common table expression" so as not to repeat queries, the idea is that for each row we will make a LEFT JOIN
with the same rows whose number is equal or previous. Here it is fundamental to establish the Order, although the final accumulated is always the same, each partial will depend on the order that we establish by ROW_NUMBER() OVER (ORDER BY Id) RN
. in this case I use the ID
of each original record.
If we review, the result would be something like this:
╔══════╦══════════╦══════╗
║ Id ║ Nombres ║ Gtb ║
╠══════╬══════════╬══════╣
║ 1,00 ║ Pedro* ║ 0,50 ║
╠══════╬══════════╬══════╣
║ 3,00 ║ Carla* ║ 0,80 ║
╠══════╬══════════╬══════╣
║ 4,00 ║ Johan* ║ 1,20 ║
╠══════╬══════════╬══════╣
║ 6,00 ║ Cecilia* ║ 6,20 ║
╚══════╩══════════╩══════╝
And now, we use the temporary variable type @TablaResultados
to update the final table, only those rows that we have originally filtered
UPDATE @Tabla
SET Gtb = T2.Gtb
FROM @Tabla T1
INNER JOIN @TablaResultados T2
ON T1.Id = T2.Id
SELECT *
FROM @Tabla
The final result:
╔══════╦══════════╦════════════╦════════╦══════╗
║ Id ║ Nombres ║ Attributos ║ Altura ║ Gtb ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 1,00 ║ Pedro* ║ 0,50 ║ 5,10 ║ 0,50 ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 2,00 ║ Anna ║ 0,60 ║ 4,30 ║ ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 3,00 ║ Carla* ║ 0,30 ║ 6,40 ║ 0,80 ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 4,00 ║ Johan* ║ 0,40 ║ 3,40 ║ 1,20 ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 5,00 ║ Bryan ║ 10,00 ║ 6,00 ║ ║
╠══════╬══════════╬════════════╬════════╬══════╣
║ 6,00 ║ Cecilia* ║ 5,00 ║ 5,70 ║ 6,20 ║
╚══════╩══════════╩════════════╩════════╩══════╝