MySQL查找特定产品的重复购买者

xcitsw88  于 8个月前  发布在  Mysql
关注(0)|答案(4)|浏览(94)

这是一个比我通常遇到的报告问题稍微复杂一些的问题,我想知道客户已经回购了多少次单个产品列表(比如说,有些产品的销售量很高,但我们想知道有多少是首次购买的,有多少是回购的)。

items_purchased:
+----------+------------+----------+
| buyer_id | listing_id | quantity |
+----------+------------+----------+
|     1234 |       5678 |        1 |
|     1234 |       3456 |        1 |
|     9012 |       3456 |        2 |
|     7901 |       5678 |        1 |
|     1234 |       5678 |        1 |
+----------+------------+----------+

字符串
从这些数据,我可以看到上市5678已购买3次,但回购一次.上市3456已购买两次,但从未回购.我想建立一个报告如下:

+------------+-----------+-------------+-----------------+
| listing_id | purchases | repurchases | repurchase_rate |
+------------+-----------+-------------+-----------------+
|       5678 |      1364 |         152 | 11%             |
|       3456 |       892 |         289 | 32%             |
|       3284 |        51 |          30 | 59%             |
|       8763 |         8 |           0 | 0%              |
+------------+-----------+-------------+-----------------+


我想我需要一个DISTINCTGROUP BY的地方,肯定是一个SUM我猜,但我难住了如何做到这一点。

mkh04yzy

mkh04yzy1#

您可以:

select *, 1.0 * repurchases / purchases as repurchase_rate
from (
  select listing_id, sum(cnt) as purchases, sum(cnt - 1) as repurchases
  from (
    select listing_id, buyer_id, count(*) as cnt
    from items_purchased
    group by listing_id, buyer_id
  ) x
  group by listing_id
) y

字符串
测试结果:

listing_id  purchases  repurchases  repurchase_rate        
 ----------- ---------- ------------ ---------------------- 
 5678        3          1            0.33333
 3456        2          0            0.00000


请参见db<>fiddle上的运行示例。

bprjcwpo

bprjcwpo2#

在我的脑海中,你可以构建一个CTE,将特定listing_id的购买计数汇总为buyer_id,每个减去1以包括 * 仅 * 回购:

WITH repurchases AS
(
    SELECT
        listing_id,
        SUM(repurchases) AS repurchases
    FROM
    (
        SELECT
            listing_id,
            buyer_id,
            COUNT(1) - 1 AS repurchases
        FROM
            items_purchased
        GROUP BY
            listing_id,
            buyer_id
    ) repurchases_by_buyer
    GROUP BY
        listing_id
)
SELECT
    items_purchased.listing_id,
    COUNT(1) AS purchases,
    (SELECT repurchases FROM repurchases WHERE repurchases.listing_id = items_purchased.listing_id) AS repurchases
FROM
    items_purchased
GROUP BY
    items_purchased.listing_id

字符串
DB Fiddle
考虑到子查询的无偿使用,这可能不是计算效率最高的方法,但我相信还有进一步优化的空间来适应规模化的使用。

ego6inou

ego6inou3#

使用count()count() - count(distinct)分别计算购买和回购。

SELECT listing_id, COUNT(buyer_id) purchases, 
COUNT(buyer_id) - COUNT(DISTINCT buyer_id) repurchases,
CONCAT(ROUND(100 * (1 - COUNT(DISTINCT buyer_id)/COUNT(buyer_id))), '%')  repurchase_rate
FROM items_purchased 
GROUP BY listing_id;

字符串
| listing_id|购买|回购|回购利率|
| --|--|--|--|
| 3456 | 2 | 0 |0%的百分比|
| 5678 | 3 | 1 |百分之三十三|
db fiddle

jc3wubiy

jc3wubiy4#

SELECT
  p.listing_id,
  COUNT(p.listing_id) AS purchases,
  COUNT(r.listing_id) AS repurchases,
  ROUND((COUNT(r.listing_id) / COUNT(p.listing_id)) * 100, 2) AS repurchase_rate
FROM
  (SELECT listing_id, buyer_id, MIN(quantity) AS first_purchase
   FROM items_purchased
   GROUP BY listing_id, buyer_id) AS first_purchases
LEFT JOIN items_purchased AS p
  ON first_purchases.listing_id = p.listing_id
LEFT JOIN items_purchased AS r
  ON first_purchases.listing_id = r.listing_id
  AND first_purchases.buyer_id = r.buyer_id
  AND r.quantity > first_purchases.first_purchase
GROUP BY p.listing_id;

字符串
此查询执行以下操作:

  • 子查询first_purchases标识每个buyer_idlisting_id的第一次购买
  • 然后,主查询LEFT JOIN items_purchased表两次:一次是计算所有购买(p),一次是计算回购(r
  • repurchases计数经过筛选,仅包括quantity数量大于first_purchase数量的采购
  • 最后,它计算repurchase_rate并格式化输出

需要注意的是,上面的查询假设回购是指后续的采购数量大于第一次采购数量,请根据您具体的回购定义调整逻辑。

相关问题