SQL 按最初购买的产品列出其他购买的产品并计算买家
Posted
技术标签:
【中文标题】SQL 按最初购买的产品列出其他购买的产品并计算买家【英文标题】:SQL List other products bought and count buyers, by product originally purchased 【发布时间】:2018-09-01 23:30:09 【问题描述】:经过多年阅读答案,终于到了我自己提出问题的时候了。
我有一份购买的产品列表和唯一的客户 ID:
+---------+--------+
| Product | Buyer |
+---------+--------+
| Apples | Rod |
| Apples | Jane |
| Apples | Freddy |
| Bananas | Rod |
| Bananas | Jane |
| Bananas | Freddy |
| Bananas | Zippy |
| Pears | Rod |
| Pears | Zippy |
+---------+--------+
我想在 Netezza SQL 中生成以下输出:
+-----------+-------------+------------------------+---------------------+
| Product A | Buyers of A | A Buyers Also Bought B | No of A Buyers of B |
+-----------+-------------+------------------------+---------------------+
| Apples | 3 | Bananas | 3 |
| Apples | 3 | Pears | 1 |
| Bananas | 4 | Apples | 3 |
| Bananas | 4 | Pears | 2 |
| Pears | 2 | Apples | 1 |
| Pears | 2 | Bananas | 2 |
+-----------+-------------+------------------------+---------------------+
..这样我就可以看到每个产品的总购买者。至关重要的是,我还想查看对于每种产品,在这些购买者中,有多少人购买了同一列表中的其他产品。 编辑:重要的是要重申,如果他们没有也购买产品 A,我不应该让任何买家出现在 B 的列中。
请问最有效的方法是什么?
(然后我会计算出 B 购买 A 的百分比,但这部分很简单)。
谢谢!
【问题讨论】:
【参考方案1】:您可以创建计数摘要,然后与自身交叉连接,排除相同的匹配项。
像这样:
SELECT
A.Product,
A.Buyers,
B.Product,
B.Buyers
FROM (
SELECT
Product
count(*) AS Buyers
FROM
ProductBuyers
GROUP BY
) AS A
CROSS JOIN (
SELECT
Product
count(*) AS Buyers
FROM
ProductBuyers
GROUP BY
) AS B
WHERE
A.Product != B.Product
【讨论】:
感谢您的快速响应!但是,这似乎对我不起作用 - 每个产品的两列中的数字都是相同的(每次只给我表格中的总数)。他们只是订购不同。为了让它运行,我还必须在子查询 A 和 B 中的每个 GROUP BY 和 Product 后面添加“1”。【参考方案2】:普通购买的基本数据是自加入和group by
:
select p1.product, p2.product, count(*) as in_common
from purchases p1 join
purchases p2
on p1.buyer = p2.buyer
group by p1.product, p2.product;
要获得一个(或另一个)的计数,则为join
:
select p1.product, p2.product, pp.cnt, count(*) as in_common
from purchases p1 join
purchases p2
on p1.buyer = p2.buyer join
(select p1.product, count(*) as cnt
from purchases
group by p1.product
) pp
on pp.product = p1.product
group by p1.product, p2.product, pp.cnt;
或者,您可以使用窗口函数:
select p1.product, p1.cnt, p2.product, count(*) as in_common
from (select p1.*,
count(*) over (partition by p1.product) as cnt
from purchases p1
) p1 join
purchases p2
on p1.buyer = p2.buyer
group by p1.product, p2.product, p1.cnt;
Here 是一个 rextester,显示它正在工作。
【讨论】:
也感谢您的快速响应!不幸的是,我得到的结果与 Alan 的代码相同。无论如何,它只是给了我每种产品的总计数。可能我在最初的问题中没有说得足够清楚 - 我只在第二个计数中寻找 both 产品的买家,而不是所有买家。输出表应该更清楚地说明这一点。当然,除非我使用的代码不正确。 @baaweepgranna 。 . .这根本不是真的,除非 Netezza 被破坏了。我已经包含了一个 Rextester,它显示它在 Postgres 中工作。以上是关于SQL 按最初购买的产品列出其他购买的产品并计算买家的主要内容,如果未能解决你的问题,请参考以下文章
GA BigQuery - 购买产品 x 的用户也购买了产品 abc 然后仅过滤列出完整的交易,其中 x 是交易的一部分