2017-06-30 3 views
1

Ok génies Postgres, j'ai besoin d'aide. J'essaie de tracer une grande quantité de données et je veux préparer les données du mieux que je peux dans la base de données avant de les envoyer au frontend. J'utilise Postgres 9.6Postgres éléments de comptage et de la colonne par date

J'ai un ensemble de résultats comme celui-ci:

Source | Date 
--------|------------ 
Email | 2017-06-01 
Email | 2017-06-01 
Email | 2017-06-03 
Email | 2017-06-03 
Email | 2017-06-03 
Email | 2017-06-04 
Email | 2017-06-06 
Email | 2017-06-06 
Email | 2017-06-07 
Banner | 2017-06-01 
Banner | 2017-06-02 
Banner | 2017-06-03 
.... 

Et je dois obtenir tout compté par jour puis en colonne et s'il y a un résultat nul pour une date que j'ai besoin zerofilled .

Résultat souhaité:

Source | 2017-06-01 | 2017-06-02 | 2017-06-03 | ... | 2017-06-07 
--------|-------------|-------------|-------------|------|------------ 
Email | 2   | 0   | 3   | ... | 1 
Banner | 1   | 1   | ...   

J'espère que cela a un sens, je vous remercie.

+0

combien de colonnes de dates avez-vous besoin? est-ce corrigé? –

+0

Non, les colonnes ne sont pas corrigées. Je pourrais aussi peut-être renvoyer une seule colonne qui est json de toutes les valeurs mais elle devrait avoir une valeur nulle si elle n'a aucun enregistrement pour cette date. –

Répondre

0

Vous pouvez utiliser:

SELECT 
    * 
FROM 
    crosstab(
    $$ 
     SELECT "Source", "Date"::text, count("Date") 
     FROM t 
     GROUP BY "Source", "Date" 
     ORDER BY "Source" 
    $$, 
    $$ 
     SELECT cast(d as date) 
     FROM generate_series(date '2017-06-01', date '2017-06-10', interval '1 day') as s(d) 
    $$ 
    ) AS 
    (
     "Source" text, 
     "2017-06-01" bigint, 
     "2017-06-02" bigint, 
     "2017-06-03" bigint, 
     "2017-06-04" bigint, 
     "2017-06-05" bigint, 
     "2017-06-06" bigint, 
     "2017-06-07" bigint, 
     "2017-06-08" bigint, 
     "2017-06-09" bigint, 
     "2017-06-10" bigint 
    ) ; 

qui utilise les crosstab(text source_sql, text category_sql), spécifiques à PostgreSQL et qui a besoin de l'extension tablefunc, ou vous pouvez aller le "pivot SQL classique":

SELECT 
    "Source" 
    ,COUNT(CASE WHEN "Date" = '2017-06-01' THEN 1 END) AS "2017-06-01" 
    ,COUNT(CASE WHEN "Date" = '2017-06-02' THEN 1 END) AS "2017-06-02" 
    ,COUNT(CASE WHEN "Date" = '2017-06-03' THEN 1 END) AS "2017-06-03" 
    ,COUNT(CASE WHEN "Date" = '2017-06-04' THEN 1 END) AS "2017-06-04" 
    ,COUNT(CASE WHEN "Date" = '2017-06-05' THEN 1 END) AS "2017-06-05" 
    ,COUNT(CASE WHEN "Date" = '2017-06-06' THEN 1 END) AS "2017-06-06" 
    ,COUNT(CASE WHEN "Date" = '2017-06-07' THEN 1 END) AS "2017-06-07" 
    ,COUNT(CASE WHEN "Date" = '2017-06-08' THEN 1 END) AS "2017-06-08" 
    ,COUNT(CASE WHEN "Date" = '2017-06-09' THEN 1 END) AS "2017-06-09" 
    ,COUNT(CASE WHEN "Date" = '2017-06-10' THEN 1 END) AS "2017-06-10" 
FROM 
    t 
GROUP BY 
    "Source" 
ORDER BY 
    "Source" ; 
 
Source | 2017-06-01 | 2017-06-02 | 2017-06-03 | 2017-06-04 | 2017-06-05 | 2017-06-06 | 2017-06-07 | 2017-06-08 | 2017-06-09 | 2017-06-10 
:----- | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: 
Banner |   1 |   1 |   1 |   0 |   0 |   0 |   0 |   0 |   0 |   0 
Email |   2 |   0 |   3 |   1 |   0 |   2 |   1 |   0 |   0 |   0 

Les deux retourneront les mêmes valeurs, la différence étant que la seconde vous donnera «0» et la première vous donnera «nul» quand il n'y a pas de valeurs à compter.

dbfiddle here

+0

Ok question de suivi, est-il un moyen de construire l'instruction select de sorte que la plage de dates est dynamique. Dites-moi de créer une fonction où je passe les dates de début et de fin, puis de construire dynamiquement les colonnes à partir de cela? –

+1

Vous pouvez le faire avec une fonction avec SQL dynamique. Vérifiez https://www.postgresql.org/docs/current/static/ecpg-dynamic.html – joanolo

+0

Wow cela devient un peu (ou beaucoup) sur ma tête. Y a-t-il un exemple que vous pouvez éventuellement lier à ce qui pourrait être similaire. J'ai essayé googling postgres et sql dynamique et ai eu une tonne de différentes tangentes. Si ce n'est pas merci, cela a déjà été extrêmement utile. –