2015-12-19 1 views
3

Tenir compte des données d'événements suivants d'une valeur de PostgreSQL 9.4:SQL pour la table de fréquence bidirectionnelle en utilisant une variable chaîne

 eventTime  | eventName 
2015-09-25 18:00:00 | 'AAA' 
2015-09-25 17:00:00 | 'BBB' 
2015-09-25 16:00:00 | 'BBB' 
2015-09-25 15:00:00 | 'BBB' 
2015-09-25 14:00:00 | 'AAA' 
2015-09-26 13:00:00 | 'CCC' 
2015-09-26 12:00:00 | 'AAA' 
2015-09-26 11:00:00 | 'BBB' 
2015-09-26 10:00:00 | 'CCC' 
2015-09-26 09:00:00 | 'BBB' 
2015-09-27 08:00:00 | 'AAA' 
2015-09-27 07:00:00 | 'CCC' 
2015-09-27 05:00:00 | 'CCC' 
2015-09-27 04:00:00 | 'CCC' 
2015-09-27 03:00:00 | 'CCC' 
2015-09-27 02:00:00 | 'AAA' 

Bien que simples tables à base count() sont simples, par exemple:

SELECT eventTime, count(1) 
    from (SELECT data->>'eventName' as eventName, 
     date_trunc('day', to_timestamp(data->>'timestamp','YYYY-MM-DDZHH24:MI:SS.MS')::timestamp without time zone) AS eventTime 
     FROM sidetrack where (data->>'eventName' = 'AAA') IS TRUE) AS tmptab 
GROUP BY eventTime 
ORDER BY eventTime ASC 

Il est seulement possible de compter l'occurrence d'une seule valeur de eventName. Je ne suis pas très expérimenté avec SQL et j'ai du mal à trouver un moyen de créer une table de fréquence bidirectionnelle. Dans cet exemple, le résultat serait:

 day | 'AAA' | 'BBB' | 'CCC' 
------------+-------+-------+------- 
2015-09-25 | 2 | 3 | 0 
2015-09-26 | 1 | 2 | 2 
2015-09-27 | 2 | 0 | 4 

Il existe des exemples où les variables avec des valeurs numériques sont comptées en utilisant with_bucket(), mais ne généralise pas les champs contenant des chaînes.

J'ai essayé imbriquées sous WITH, choisit comme:

WITH 
    foo AS (
     SELECT ... 
    ), 
    bar AS (
     SELECT ... 
    FROM foo 
    ), 
SELECT * 
FROM bar; 

Et avec REJOINT extérieur, mais je ne peux pas casser cela.

+0

Vos extraits de requête à partir des valeurs JSON , mais votre question ne mentionne même pas JSON. Veuillez clarifier et fournir la définition de la table et, comme toujours, votre version de Postgres. –

+0

Bonjour Erwin, vous avez raison de dire que le fait que le texte soit extrait des clés JSON est indépendant du défi de la table de fréquence. Je fais du prototypage avec une table de test qui n'a pas JSON. J'ai utilisé le snippt avec le JSON comme exemple de travail. La version de Postgres est 9.4. Merci. – JohnH

Répondre

1

Vous pouvez simplement utiliser une instruction CASE pour chaque colonne pour générer un 1 pour une correspondance, puis SUM toutes les lignes, quelque chose comme;

SELECT date_trunc('day', timestamp) AS time, 
     SUM(CASE WHEN "eventName" = 'AAA' THEN 1 ELSE 0 END) AAA, 
     SUM(CASE WHEN "eventName" = 'BBB' THEN 1 ELSE 0 END) BBB, 
     SUM(CASE WHEN "eventName" = 'CCC' THEN 1 ELSE 0 END) CCC 
FROM sidetrack 
GROUP BY date_trunc('day', timestamp) 
ORDER BY date_trunc('day', timestamp) ASC 

An SQLfiddle to test with.

+0

Merci; cela fonctionne bien lorsque le nombre de valeurs est connu à l'avance. C'est souvent le cas. – JohnH

0

Cette requête sélectionne nombre d'événements de chaque jour:

select day, event, count(*) 
from (
    select 
     left(date_trunc('day', (data->>'timestamp')::timestamp)::text, 10) as day, 
     data->>'eventName' as event 
    from sidetrack 
    ) s 
group by 1, 2 
order by 1 asc, 2; 

    day  | event | count 
------------+-------+------- 
2015-09-25 | AAA |  2 
2015-09-25 | BBB |  3 
2015-09-26 | AAA |  1 
2015-09-26 | BBB |  2 
2015-09-26 | CCC |  2 
2015-09-27 | AAA |  2 
2015-09-27 | CCC |  4 
(7 rows) 

Vous pouvez utiliser la requête en crosstab() fonction:

create extension if not exists tablefunc; 

select * from crosstab (
    $q$ 
     select day, event, count(*) 
     from (
      select 
       left(date_trunc('day', (data->>'timestamp')::timestamp)::text, 10) as day, 
       data->>'eventName' as event 
      from sidetrack 
      ) s 
     group by 1, 2 
     order by 1 asc 
    $q$, 
    $q$ 
     values ('AAA'), ('BBB'), ('CCC') 
    $q$) 
as ct (day text, "AAA" int, "BBB" int, "CCC" int); 

    day  | AAA | BBB | CCC 
------------+-----+-----+----- 
2015-09-25 | 2 | 3 |  
2015-09-26 | 1 | 2 | 2 
2015-09-27 | 2 |  | 4 
(3 rows) 
+0

Merci, très utile. – JohnH