J'ai écrit la requête qui me donne des séries chronologiques sur une plage et un intervalle de date indiquant les revenus pour chaque intervalle de temps:
SELECT
interval_date,
coalesce(campaign_revenue,0) AS campaign_revenue,
FROM
-- generate_series helps fill the empty gaps in the following JOIN
generate_series(
$2::timestamp,
$3::timestamp,
$4) AS interval_date -- could be '1 day', '1 hour' or '1 minute'.
LEFT OUTER JOIN
-- This SELECT gets all timeseries rows that have data
(SELECT
date_trunc($4, s.created) AS interval,
SUM(s.revenue) campaign_revenue
FROM
sale_event AS s
WHERE
s.campaignid = $1 AND s.created BETWEEN $2 AND $3 AND s.event_type = 'session_closed'
GROUP BY
interval) results
ON
(results.interval = interval_date);
La requête prend chaque rangée de sale_event
table, tronque la date de création à un intervalle (aligne le created
horodatage avec la granularité souhaitée de la série temporelle), des groupes de cet intervalle de temps et résume les colonnes revenue
sur les lignes où event_type
est session_closed
.
Cela fonctionne très bien et me donne les revenus dans l'intervalle spécifié. Le résultat peut ressembler à:
interval_date | campaign_revenue
------------------------------------
2018-08-05 | 0.0
2018-08-06 | 1.5
2018-08-07 | 0.0
2018-08-08 | 0.5
2018-08-09 | 1.0
Lorsque la plage fournie est 2018-08-05 - 2018-08-09
et interval = '1 day'
.
Je tiens à ajouter au résultat la somme des revenus jusqu'à cette date. Donc, si avant 2018-08-05
il y a un chiffre d'affaires total de 10.0
, le résultat serait:
interval_date | campaign_revenue | total_campaign_revenue
-----------------------------------------------------------------
2018-08-05 | 0.0 | 10.0
2018-08-06 | 1.5 | 11.5
2018-08-07 | 0.0 | 11.5
2018-08-08 | 0.5 | 12.0
2018-08-09 | 1.0 | 13.0
Si je comprends bien, vous pouvez simplement ajouter une fonction de fenêtre en dehors de votre requête comme:
SELECT interval_date, campaign_revenue
, SUM(campaign_revenue) OVER (ORDER BY interval_date)
+ (SELECT SUM(revenue)
FROM sale_event
WHERE s.campaignid = $1
AND s.created < $2
AND s.event_type = 'session_closed') as total_campaign_revenue
FROM (
SELECT interval_date
, coalesce(campaign_revenue,0) AS campaign_revenue
FROM
-- generate_series helps fill the empty gaps in the following JOIN
...
interval) results
ON (results.interval = interval_date)
);
Une autre option consiste à appliquer directement la fonction de fenêtre et utilisez une clause de filtrage pour campaign_revenue