简体   繁体   English

SQL - 查找购买所有产品的客户

[英]SQL - Find customers who bought all products

Suppose I have 2 tables:假设我有 2 个表:

Table A表A

C_ID   P_ID
   1      1
   1      2
   2      1

Table B表B

P_ID
   1
   2

In Table A, C_ID and P_ID serve as PK, in Table B P_ID is the PK表A中C_IDP_ID作为PK,表B中P_ID为PK

I want to find all C_ID that bought all products in B (basically all P_ID in B).我想找到所有购买 B 中所有产品的 C_ID(基本上是 B 中的所有 P_ID)。 In the example above that would C_ID = 1在上面的示例中, C_ID = 1

Can you check if below is correct?你能检查一下下面是否正确吗? Any alternatives that are more efficient/easier?任何更有效/更容易的替代方案?

SELECT A.C_ID
FROM A
JOIN B ON A.P_iD = B.P_ID
GROUP BY A.C_ID
HAVING COUNT(DISTINCT A.P_ID) >= (SELECT COUNT(DISTINCT P_ID) FROM B)

Thanks!谢谢!

following query works with MySQL and SQL Server.以下查询适用于 MySQL 和 SQL 服务器。

you can do this without JOIN你可以在没有JOIN的情况下做到这一点

select 
    c_id
from tableA 
group by 
    c_id
having count(distinct p_id) = (select count(*) from tableB)

The other answer is not correct, as it only verifies that a customer bought as many distinct items as there are items in the product table.另一个答案不正确,因为它只验证客户购买了与产品表中的项目一样多的不同项目。 If however you table looked like this:但是,如果您的表看起来像这样:

C_ID   P_ID
   1      1
   1      3
   2      1

the query would return customer 1 even though Customer 1 did not but all the products (namely, they did not buy product P_ID=2 .查询将返回客户 1,即使客户 1 没有购买所有产品(即,他们没有购买产品P_ID=2

Generalized Solution广义解

what you are looking for is called a division query.您要查找的内容称为分部查询。 The strategy is based on a double negation, think:该策略基于双重否定,认为:

"give me all the customers for which there is no product, that has never been purchased" “给我所有没有产品、从未购买过的客户”

in SQL:在 SQL 中:

-- define a customer table
WITH customers as (
     SELECT DISTINCT C_ID
     FROM A)

-- all customers who have not
SELECT * 
FROM customers as outer
WHERE NOT EXISTS
(   -- all products which have not
    SELECT * 
    FROM B as inner
    WHERE NOT EXISTS
    (   -- ever been purchased
        SELECT* 
        FROM A as matchtable
        WHERE matchtable.C_ID=outer.C_ID
        AND matchtable.P_ID=inner.P_ID)
 )
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM