2017-05-24 1 views
1

J'ai une table comme cet exemple:Distinct sur colonne et trouver somme pour quelques mois dans Postgres

 purchase_datetime customer_id value purchase_id 
    2013-01-08 17:13:29  45236  92  2526 
    2013-01-03 15:42:35  45236  16  2565 
    2013-01-03 15:42:35  45236  16  2565 
    2013-03-08 09:04:52  45236  636  2563 
    2013-12-08 12:12:24  45236  23  2505 
    2013-12-08 12:12:24  45236  23  2505 
    2013-12-08 12:12:24  45236  23  2505 
    2013-12-08 12:12:24  45236  23  2505 
    2013-07-08 22:35:53  35536  73  2576 
    2013-07-08 09:52:03  35536  4  5526 
    2013-10-08 16:23:29  52626  20  2226 
... 
    2013-04-08 17:49:31  52626  27  4526 
    2013-12-09 20:40:53  52626  27  4626 

Maintenant je dois trouver la somme totale dépensée (valeur) par le client pour chaque achat effectué par ce client (purchase_id) au cours des derniers mois. Mais j'ai un problème car il y a doublé purchase_id, donc je dois faire Distinct sur purchase_id.

C'est ce que j'ai obtenu jusqu'à présent sans distincte, je ne sais pas comment aborder distincte.

Select customer_id 
    sum(case when (date '2017-01-01' - purchase_datetime::DATE <=30) then value else 0 end) as 1month, 
    sum(case when (date '2017-01-01' - purchase_datetime::DATE <=90) then value else 0 end) as 3month, 
    sum(case when (date '2017-01-01' - purchase_datetime::DATE <=180) then value else 0 end) as 6month, 
    sum(case when (date '2017-01-01' - purchase_datetime::DATE <=360) then value else 0 end) as 12month 

FROM table_data 
GROUP BY (customer_id) 
ORDER BY amount_1month DESC; 

Peut-être est-ce mieux avec window func?

sortie souhaitée:

purchase_datetime customer_id value purchase_id 
    2013-01-08 17:13:29  45236  92  2526 
    2013-01-03 15:42:35  45236  16  2565 
    2013-03-08 09:04:52  45236  636  2563 
    2013-12-08 12:12:24  45236  23  2505 
    2013-07-08 22:35:53  35536  73  2576 
    2013-07-08 09:52:03  35536  4  5526 
    2013-10-08 16:23:29  52626  20  2226 
... 
    2013-04-08 17:49:31  52626  27  4526 
    2013-12-09 20:40:53  52626  27  4626 
+1

Je ne comprends pas pourquoi vous voulez DISTINCT ici? Votre GROUP BY ne renvoie aucune ligne en double. – jarlh

+0

@jarlh Que faire si je laisse tomber un groupe? Je ne suis pas sûr, mais quand j'ai fait cela, j'ai eu un grand nombre à cause de plusieurs lignes avec les mêmes données, juste comme la cinquième à la neuvième rangée. – jovicbg

+0

Avec le GROUP BY, vous obtiendrez une ligne par customer_id. N'est-ce pas ce que tu veux? – jarlh

Répondre

1

Vous pouvez sélectionner un sous-requête, et d'utiliser un DISTINCT (ou GROUP BY) dans cette sous-requête.

Par exemple:

SELECT 
    customer_id, 
    sum(case when purchase_datetime::DATE between current_date - interval '1 month' and current_date then "value" else 0 end) as "1month", 
    sum(case when purchase_datetime::DATE between current_date - interval '3 month' and current_date then "value" else 0 end) as "3month", 
    sum(case when purchase_datetime::DATE between current_date - interval '6 month' and current_date then "value" else 0 end) as "6month", 
    sum(case when purchase_datetime::DATE between current_date - interval '1 year' and current_date then "value" else 0 end) as "12month" 
FROM (
    select 
    distinct purchase_id, customer_id, purchase_datetime, "value" 

    -- distinct on (purchase_id) customer_id, purchase_datetime, "value" 
    -- Note: with this type of distinct you assume that for each purchase_id there is only 1 combination of the 3 other field values. 

    from table_data 
) p 
GROUP BY customer_id 
ORDER BY "1month" DESC; 

Testdata:

create table table_data (purchase_datetime timestamp(0),customer_id int,"value" int,purchase_id int); 
insert into table_data (purchase_datetime,customer_id,"value",purchase_id) values 
(current_timestamp - interval '11 month',45236,92,2526), 
(current_timestamp - interval '11 month',45236,16,2565), 
(current_timestamp - interval '1 month',45236,16,2565), 
(current_timestamp - interval '2 month',45236,636,2563), 
(current_timestamp - interval '5 month',45236,23,2505), 
(current_timestamp - interval '5 month',45236,23,2505), 
(current_timestamp - interval '5 month',45236,23,2505), 
(current_timestamp - interval '3 month',35536,73,2576), 
(current_timestamp - interval '2 month',35536,4,5526), 
(current_timestamp - interval '1 month',52626,20,2226), 
(current_timestamp - interval '6 month',52626,27,4526), 
(current_timestamp - interval '6 month',52626,27,4626); 
0
select customer_id, sum(value) 
from (
    select distinct on (purchase_id) * 
    from t 
) s 
where purchase_datetime >= '2017-07-01' 
group by 1 
; 
customer_id | sum 
-------------+----- 
     35536 | 77 
     52626 | 20 
     45236 | 23