Compter les données à l'aide de plusieurs plages de dates

14

Cela a probablement déjà été demandé, mais je ne peux pas le comprendre. J'ai une phone_clickstable (sql fiddle http://sqlfiddle.com/#!15/855e0/1 )

CREATE TABLE phone_clicks (
    id integer NOT NULL,
    date date NOT NULL,
    industry_id integer NOT NULL,
    clicks integer DEFAULT 0 NOT NULL
);

insert into phone_clicks(id, date, industry_id, clicks)
values
(1, '2015-03-16', 1, 15),
(2, '2015-03-16', 2, 7),
(3, '2015-03-16', 3, 0),
(4, '2015-03-17', 1, 12),
(5, '2015-03-17', 3, 4),
(6, '2015-03-17', 4, 22),
(7, '2015-03-18', 1, 19),
(8, '2015-03-18', 2, 35);

Ce tableau contient le nombre d'événements de clics téléphoniques pour plusieurs industries_id et dates.

Est-il possible de compter ces clics pour tous les ID_industrie disponibles avec plusieurs plages de dates comme conditions? Je voudrais avoir cette sortie:

------------------------------------------------
industry_id |  today | yesterday | last 3 days |
------------------------------------------------
1           |  19    | 12        | 46          |
------------------------------------------------
2           |  35    | 0         | 42          |
------------------------------------------------
3           |  0     | 4         | 4           |
------------------------------------------------
4           |  0     | 22        | 22          |
------------------------------------------------

J'ai essayé d'utiliser le comptage avec la partition par date, mais je suis arrivé nulle part. Est-il possible de sélectionner ces données dans une seule requête? Un avantage supplémentaire serait de pouvoir spécifier les mois précédents comme des plages de dates: aujourd'hui, hier, mars, février, janvier, etc.

MISE À JOUR : J'ai mis à jour le violon pour définir le mois en cours, les mois précédents et le mois précédent comme plages de dates. SQL Fiddle: http://sqlfiddle.com/#!15/855e0/46

J'utilise PostgreSQL 9.3, mais les solutions 9.4 sont les bienvenues, car nous y migrerons bientôt.

Valentin Vasilyev
la source

Réponses:

8
select  industry_id
,       sum(case when current_date <= date then clicks end) as today 
,       sum(case when current_date-1 <= date and
                      date < current_date then clicks end) as yesterday
,       sum(case when current_date-4 <= date and 
                      date < current_date-1 then clicks end) as last3days
from    phone_clicks
group by
        industry_id

Voyez-le dans votre SQLFiddle.

Andomar
la source
7

Dans la version 9.4, nous pourrons utiliser la FILTERclause:

select  
    t.industry_id,
    sum(t.clicks) filter (where t.date = current_date) 
        as today,
    sum(t.clicks) filter (where t.date = current_date - interval '1 day')
        as yesterday,
    sum(t.clicks) filter (where t.date >= current_date - interval '2 days'
                            and t.date <= current_date) 
        as last_3_days
from 
    phone_clicks as t
group by 
    t.industry_id ;

Essayé dans SQLfiddle .

ypercubeᵀᴹ
la source
Ressemble beaucoup mieux, le filtre est un excellent sucre syntaxique! La requête suppose qu'il dates'agit d'une colonne de type dateet non timestamp. Cette hypothèse m'a parfois brûlé
Andomar
1
@Andomar, oui, j'ai généralement des plages ouvertes-fermées dans les requêtes date / datetime / timestamp. Plus difficile d'être mordu par des changements dans les types de données.
ypercubeᵀᴹ