Đưa ra bảng kiểm tra sau (mà bạn nên cung cấp):
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
Bảng auth_user
không liên quan đến vấn đề.
Sử dụng tstamp
dưới dạng tên cột vì tôi không sử dụng các loại cơ sở làm số nhận dạng.
Tôi sẽ sử dụng hàm window lag()
để xác định những người mua nhiều lần. Để giữ cho nó ngắn gọn, tôi kết hợp các hàm tổng hợp và cửa sổ trong một cấp truy vấn. Lưu ý rằng các chức năng cửa sổ được áp dụng sau tổng hợp các chức năng.
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;
Kết quả:
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
Tôi đã mở rộng câu hỏi của bạn để cung cấp sự khác biệt giữa số lượng giao dịch và số lượng người mua.
OR NULL
cho repeat_transaction
phục vụ để chuyển đổi FALSE
thành NULL
, vì vậy những giá trị đó không được tính bằng count()
trong bước tiếp theo.