web-dev-qa-db-fra.com

Valeur cumulée de la ligne en cours + somme des lignes précédentes

Comment feriez-vous pour transformer une colonne en une table à partir de ceci: 

ColumnA   ColumnB
2           a
3           b
4           c
5           d
1           a

pour ça:

ColumnA          ColumnB
3                 a
6(=3+3)           b   
10(=4+3+3)        c   
15(=5+4+3+3)      d 

Je suis intéressé de voir esp. quelle méthode vous choisiriez.

14
Sam

Comme ça:

;WITH cte
AS
(
   SELECT ColumnB, SUM(ColumnA) asum 
   FROM @t 
   gROUP BY ColumnB

), cteRanked AS
(
   SELECT asum, ColumnB, ROW_NUMBER() OVER(ORDER BY ColumnB) rownum
   FROM cte
) 
SELECT (SELECT SUM(asum) FROM cteRanked c2 WHERE c2.rownum <= c1.rownum),
  ColumnB
FROM cteRanked c1;

Cela devrait vous donner:

ColumnA    ColumnB
3             a
6             b
10            c
15            d

Voici une démo en direct

13
Mahmoud Gamal

J'éviterais généralement d'essayer de le faire, mais ce qui suit correspond à ce que vous avez demandé:

declare @T table (ColumnA int,ColumnB char(1))
insert into @T(ColumnA,ColumnB) values
(2    ,       'a'),
(3   ,        'b'),
(4  ,         'c'),
(5 ,          'd'),
(1,           'a')

;With Bs as (
    select distinct ColumnB from @T
)
select
    SUM(t.ColumnA),b.ColumnB
from
    Bs b
        inner join
    @T t
        on
            b.ColumnB >= t.ColumnB
group by
    b.ColumnB

Résultat:

            ColumnB
----------- -------
3           a
6           b
10          c
15          d

Pour les petits ensembles de données, cela ira. Toutefois, pour les grands ensembles de données, notez que la dernière ligne de la table repose sur l'obtention de la variable SUM sur tout le contenu de la table d'origine.

8

Je ne sais pas si c'est optimal, mais qu'en est-il ( SQL Fiddle ):

SELECT x.A + COALESCE(SUM(y.A),0) ColumnA, x.ColumnB
FROM
(
    SELECT SUM(ColumnA) A, ColumnB
    FROM myTable
    GROUP BY ColumnB
) x
LEFT OUTER JOIN
(
    SELECT SUM(ColumnA) A, ColumnB
    FROM myTable
    GROUP BY ColumnB
) y ON y.ColumnB < x.ColumnB
GROUP BY x.ColumnB, x.A
6
lc.
create table #T
(
  ID int primary key,
  ColumnA int,
  ColumnB char(1)
);

insert into #T
select row_number() over(order by ColumnB),
       sum(ColumnA) as ColumnA,
       ColumnB
from YourTable
group by ColumnB;

with C as
(
  select ID,
         ColumnA,
         ColumnB
  from #T
  where ID = 1
  union all
  select T.ID,
         T.ColumnA + C.ColumnA,
         T.ColumnB
  from #T as T
    inner join C
      on T.ID = C.ID + 1
)
select ColumnA,
       ColumnB 
from C
option (maxrecursion 0);

drop table #T;
3
Mikael Eriksson

Utilisation de SQL Server? ALORS

Imaginons que vous ayez une table avec 3 colonnes C_1, C_2, C_3 et classées par C_1. Utilisez simplement [Over (Order By C_1)] pour ajouter une colonne correspondant à C_3:

Sélectionnez C_1, C_2, C_3, Somme (C_3) Fini (Trier par C_1)

si vous voulez aussi le numéro de ligne, faites-le de la même manière:

Sélectionnez Row_Number () Over (Order By C_1), C_1, C_2, C_3, Sum (C_3) Over (Order By C_1).

0
Vahed

Essayez le script ci-dessous,

DECLARE @T TABLE(ColumnA INT, ColumnB VARCHAR(50));

INSERT INTO @T VALUES
    (2, 'a'),
    (3, 'b'),
    (4, 'c'),
    (5, 'd'),
    (1, 'a');

SELECT  SUM(ColumnA) OVER(ORDER BY ColumnB) AS ColumnA,ColumnB
FROM    (   SELECT  SUM(ColumnA) AS ColumnA,ColumnB
            FROM    @T  GROUP BY ColumnB )T
0
Abdul Rasheed
DECLARE @t TABLE(ColumnA INT, ColumnB VARCHAR(50));

    INSERT INTO @t VALUES
    (2,           'a'),
    (3  ,         'b'),
    (4   ,        'c'),
    (5    ,       'd'),
    (1     ,      'a');

    ;WITH cte
    AS
    (
        SELECT  ColumnB, sum(ColumnA) value,ROW_NUMBER() OVER(ORDER BY ColumnB) sr_no FROM @t group by ColumnB    
    )

    SELECT ColumnB
    ,SUM(value) OVER (   ORDER BY  ColumnB  ROWS BETWEEN UNBOUNDED PRECEDING  AND  0  PRECEDING) 
    FROM cte c1;
0
M Danish