Angesichts der folgenden Testtabelle (die Sie bereitgestellt haben sollten):
CREATE TEMP TABLE transaction (buyer_id int, tstamp timestamp);
INSERT INTO transaction VALUES
(1,'2012-01-03 20:00')
,(1,'2012-01-05 20:00')
,(1,'2012-01-07 20:00') -- multiple transactions this month
,(1,'2012-02-03 20:00') -- next month
,(1,'2012-03-05 20:00') -- next month
,(2,'2012-01-07 20:00')
,(2,'2012-03-07 20:00') -- not next month
,(3,'2012-01-07 20:00') -- just once
,(4,'2012-02-07 20:00'); -- just once
Tabelle auth_user
ist für das Problem nicht relevant.
Using tstamp
als Spaltenname, da ich keine Basistypen als Bezeichner verwende.
Ich werde die Fensterfunktion lag()
Wiederholungskäufer zu identifizieren. Um es kurz zu machen, kombiniere ich Aggregat- und Fensterfunktionen in einer Abfrageebene. Denken Sie daran, dass Fensterfunktionen nach angewendet werden Aggregatfunktionen.
WITH t AS (
SELECT buyer_id
,date_trunc('month', tstamp) AS month
,count(*) AS item_transactions
,lag(date_trunc('month', tstamp)) OVER (PARTITION BY buyer_id
ORDER BY date_trunc('month', tstamp))
= date_trunc('month', tstamp) - interval '1 month'
OR NULL AS repeat_transaction
FROM transaction
WHERE tstamp >= '2012-01-01'::date
AND tstamp < '2012-05-01'::date -- time range of interest.
GROUP BY 1, 2
)
SELECT month
,sum(item_transactions) AS num_trans
,count(*) AS num_buyers
,count(repeat_transaction) AS repeat_buyers
,round(
CASE WHEN sum(item_transactions) > 0
THEN count(repeat_transaction) / sum(item_transactions) * 100
ELSE 0
END, 2) AS buyer_retention
FROM t
GROUP BY 1
ORDER BY 1;
Ergebnis:
month | num_trans | num_buyers | repeat_buyers | buyer_retention_pct
---------+-----------+------------+---------------+--------------------
2012-01 | 5 | 3 | 0 | 0.00
2012-02 | 2 | 2 | 1 | 50.00
2012-03 | 2 | 2 | 1 | 50.00
Ich habe Ihre Frage erweitert, um den Unterschied zwischen der Anzahl der Transaktionen und der Anzahl der Käufer zu ermitteln.
Das OR NULL
für repeat_transaction
dient zur Umwandlung von FALSE
auf NULL
, sodass diese Werte nicht von count()
gezählt werden im nächsten Schritt.