Numéros en cours d'exécution

En termes simples, les nombres courants sont des nombres additionnés les uns aux autres. Par exemple, vous voulez connaître les valeurs depuis le début de l'année (YTD). L'addition de nombres est peut-être un cas souvent utilisé, mais les possibilités ne se limitent pas à cela. Vous pouvez aussi faire une moyenne mobile.

Dans le cas présent, nous travaillerons avec un exemple de cumul annuel. Supposons que nous disposions d'une Table contenant les revenus d'une certaine catégorie par mois.

ea_month    id       amount    ea_year    circle_id
April       92570    1000      2014        1
April       92571    3000      2014        2
April       92572    2000      2014        3
March       92573    3000      2014        1
March       92574    2500      2014        2
March       92575    3750      2014        3
February    92576    2000      2014        1
February    92577    2500      2014        2
February    92578    1450      2014        3   

Pour obtenir le total du mois jusqu'à aujourd'hui, vous pourriez être tenté d'utiliser une sous-requête telle que "Obtenir tous les montants des mois précédents de l'année en cours de mon produit". Cela fonctionne effectivement, mais pour chaque ligne récupérée, une sous-requête est exécutée. Cela peut facilement conduire à des milliers de requêtes et donc prendre une éternité, comme dans cet exemple :

select branch_id,
       net_profit as store_profit,
       (select sum(net_profit) from store_sales as s2 where s2.city = s1.city) as city_profit,
       store_profit / city_profit * 100 as store_percentage_of_city_profit
    from store_sales as s1
    order by branch_id;
+-----------+--------------+-------------+---------------------------------+
| BRANCH_ID | STORE_PROFIT | CITY_PROFIT | STORE_PERCENTAGE_OF_CITY_PROFIT |
|-----------+--------------+-------------+---------------------------------|
|         1 |     10000.00 |    25000.00 |                     40.00000000 |
|         2 |     15000.00 |    25000.00 |                     60.00000000 |
|         3 |     10000.00 |    19000.00 |                     52.63157900 |
|         4 |      9000.00 |    19000.00 |                     47.36842100 |
+-----------+--------------+-------------+---------------------------------+

Postgres fournit une fonction de fenêtre appelée OVER. Ainsi, dans un langage moins naturel, vous dites en SQL que vous voulez avoir un sum() SUR un ensemble de données PARTITIONNÉ par le temps et/ou le produit.

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id
                         ORDER BY ea_year, ea_month) AS cum_amt
FROM   tbl
ORDER  BY circle_id, month;

Pour obtenir un YTD, l'année doit faire partie de la PARTITION, sinon la somme sera calculée sur l'ensemble du temps.

Le calcul sera effectué par ligne. Ainsi, si la Table contient des données quotidiennes, mais que le résultat est souhaité sur une base mensuelle, les données doivent d'abord être regroupées et additionnées par mois, avant qu'un YTD sur une base mensuelle ne fonctionne.