J'ai deux colonnes qui me tiennent à cœur YearMonth et Value.

Comment puis-je additionner les 50e (1e à 50e, c'est-à-dire 1ère, 2e, ..., 50e) plus grandes valeurs de Value et créer une nouvelle colonne en fonction des critères?

Je suis capable de faire SUM(CASE WHEN Value > 100 THEN Value END) AS LargeValue mais la 1ère à la 50ème valeur la plus grande change tous les YearMonth, donc cela ne serait pas complètement correct.

Je n'ai pas trouvé de solution à cela, et la plupart des réponses trouvent plutôt que la somme la plus grande.

Le tableau ressemble à ceci (simplifié):

====================
YearMonth Value Flow
====================
201801   500   10
201801   400   -5
 ...     ...   ...
201802   700   20
201802   100  -20 
201802   50    10
1
Mataunited18 19 juin 2019 à 13:29

3 réponses

Meilleure réponse

Vous pouvez utiliser les fonctions de la fenêtre:

select t.*,
       sum(case when seqnum <= 50 then value end) over
           (partition by yearmonth) as top50_sum
from (select t.*,
             row_number() over (partition by yearmonth order by value desc) as seqnum
      from t
     ) t;

Si vous voulez juste une ligne par yearmonth dans l'ensemble de résultats, utilisez group by:

select t.yearmonth, sum(value) as top50_sum
from (select t.*,
             row_number() over (partition by yearmonth order by value desc) as seqnum
      from t
     ) t
where seqnum <= 50
group by yearmonth
2
Gordon Linoff 19 juin 2019 à 10:45

Vous pouvez utiliser une table dérivée classant la ligne par valeur décroissante et limitant le résultat à 50 lignes. Ensuite, prenez la somme de cela.

La manière dont la limitation est écrite dépend du SGBD. Dans beaucoup d’entre eux, LIMIT fonctionnera.

SELECT sum(x.value)
       FROM (SELECT t.value
                    FROM elbat t
                    ORDER BY t.value DESC
                    LIMIT 50) x;
0
sticky bit 19 juin 2019 à 10:43
SELECT t.*, 
       SUM(CASE WHEN t.r < 51 THEN t.value ELSE 0 END) OVER() runningtotal 
  FROM (
         SELECT a.yearmonth, 
                a.value, 
                RANK() OVER (ORDER BY value DESC) r 
           FROM yourtable a ) t 
 ORDER BY t.r asc

Commencez par créer un ordre de tableau classé plutôt que de créer une colonne de total cumulé pour le tableau classé uniquement pour les 50 premiers éléments.

0
Zsolt Botykai 19 juin 2019 à 16:10