如何在Postgres中找到交叉销售产品

时间:2020-08-30 21:13:54

标签: postgresql join group-by count

我必须创建一个报告,该报告显示产品的交叉销售,如果我有产品X,则意味着我需要找到该产品与其他产品一起购买的组合并计算在内。

所以我的表结构如下,

下面是相同的数据。参考是订单号,每个项目都有单独的一行,显示产品和类别详细信息。

Reference.      Product Name.        Prod ID.       Category
1000001         Honda x12            10023           Machinery
1000001         Honda cv12           10025           Machinery
1000002         Medic. 12x           10026           Medicine
1000002         Honda x12            10023           Machinery
1000003         Honda x12            10023           Machinery
1000004         Appliance x12        10033           Household
1000004         Honda x12            10023           Machinery
1000005         Bag x234             100265          Bags

我希望输出像 假设我想找到本田x12的交叉销售产品,这意味着我想知道与本田x12组合销售的所有产品以及发生特定组合计数的次数。

有人可以建议我如何在PostgreSQL(版本11)中做到这一点。

预先感谢

1 个答案:

答案 0 :(得分:3)

我认为这是一个不平等条件的自联接:

select t.prod_id prod_id1, x.prod_id prod_id2, count(*) cnt
from mytable t
inner join mytable x 
    on  x.reference = t.reference
    and x.prod_id > t.prod_id
group by t.prod_id, x.prod_id
order by 1, 2

>是故意在连接谓词中使用的,而不是<>,以避免在结果集中出现“镜像”记录。

有关示例数据,this generates

prod_id1 | prod_id2 | cnt
-------: | -------: | --:
   10023 |    10025 |   1
   10023 |    10026 |   1
   10023 |    10033 |   1

这一次为您提供所有产品的结果。如果您只想要给定产品的“对”列表,则它会稍有不同:

select t.prod_id, count(*) cnt
from mytable t
inner join mytable x 
    on  x.reference = t.reference
    and x.prod_id <> t.prod_id
where x.prod_id = 10023
group by t.prod_id
order by 1

Demo

prod_id | cnt
------: | --:
  10025 |   1
  10026 |   1
  10033 |   1