SQL Перечислите другие товары, купленные и посчитайте покупателей, по товарам, купленным изначально - PullRequest
0 голосов
/ 02 сентября 2018

После многих лет чтения ответов, пришло время самому задать вопрос.

У меня есть список купленных продуктов и уникальные идентификаторы клиентов:

+---------+--------+
| 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 |
+-----------+-------------+------------------------+---------------------+

.. так, чтобы я мог видеть, для каждого продукта, общее количество покупателей. Важно также отметить, что по каждому товару этих покупателей было куплено много других товаров в том же списке. Редактировать: Важно повторить, что у меня не должно быть покупателей в столбцах для B, если они не также покупают продукт A.

Какой самый эффективный способ сделать это, пожалуйста?

(Я тогда определю процент от покупки B, но эта часть проста).

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Базовыми данными по общим покупкам являются самостоятельные объединения и 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;

Здесь - тестер, демонстрирующий его работу.

0 голосов
/ 02 сентября 2018

Вы можете создать сводку счетчиков, а затем перекрестное соединение с самим собой, исключая такие же совпадения.

Как это:

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
...