mysql 对4个表执行Division查询(WHERE NOT EXISTS),以返回购买了所有产品的所有客户

a2mppw5e  于 2022-12-28  发布在  Mysql
关注(0)|答案(2)|浏览(118)

我想使用除法查询来获得购买了所有产品的所有客户。
模板如下所示:

SELECT *
FROM Customers AS A
WHERE NOT EXISTS
(
    SELECT *
    FROM Products AS B
    WHERE NOT EXISTS
    (
        SELECT *
        FROM Purchases AS C
        WHERE C.CustomerID= A.CustomerID
        AND C.ProductID= B.ProductID
    ));

这在本主题中有很好的解释:https://stackoverflow.com/a/71877187/17783040
我的问题是我没有3个表要连接,而是4个。除法查询应该是一样的,但我不能成功。
所以我的4张table:

  • 客户:主键为客户ID
  • 产品:PK为产品ID
  • 发票:PK为发票ID,FK为客户ID
  • 发票行:FK是发票ID和产品ID

我想实践这种查询,即使它是一个艰难的方式。我真的理解了除法查询工作的3个表在多对多的关系。
但是在我的例子中,我需要第四个表来连接CustomerID和ProductID,因为中间表InvoiceLine收集了特定ProductID和购买数量(+InvoiceID)的发票的每一行,然后Invoice表只包含InvoiceID和CustomerID。
例如,对于数据:
客户表:

CustomerID  name        surname address
1           Charles     Smith   123 main street
2           Henry       Johnson 546 Drive
3           Jennifer    Davis   65 Avenue

产品表:

ProductID   name    quantity
1           pc      12
2           usb     56
3           tv      67

发票表:

InvoiceID   CustomerID
1           1
2           3
3           2
4           3
5           1

发票行表:

InvoicelineID   ProductID   description InvoiceID
1               2           blablabla   1
2               1           blablabla   2
3               2           blablabla   2
4               1           blablabla   2
5               2           blablabla   3
6               1           blablabla   3
7               3           blablabla   4
8               3           blablabla   5

因此,我们可以在InvoiceLines表中看到的IncoiceID#2和#4的所有产品(1、2和3)都是CustomerID#3购买的
下面的查询返回数据库中的所有客户,没有任何限制,而不仅仅是购买了目录中所有产品的客户:

SELECT *
FROM Customers AS C
WHERE NOT EXISTS
(
    SELECT *
    FROM Products AS P
    WHERE NOT EXISTS
    (
        SELECT *
        FROM Invoices AS I
        WHERE NOT EXISTS
            (
                SELECT *
                FROM InvoiceLines AS L
                WHERE I.CustomerID= C.CustomerID
                AND L.InvoiceID= I.InvoiceID
                AND L.ProductID= P.ProductID
            )));

它的其他尝试也不起作用:

SELECT *
FROM Customers AS C
WHERE NOT EXISTS
(
    SELECT *
    FROM Products AS P
    WHERE NOT EXISTS
    (
        SELECT *
        FROM 
            (
            SELECT * FROM InvoiceLines AS L, Invoices AS I
            WHERE  L.InvoiceID= I.InvoiceID
            ) AS Pu
        WHERE Pu.CustomerID= C.CustomerID
        AND Pu.ProductID= P.ProductID
        )
    );

您有什么提示或建议,使其工作使用部门查询模板?

zvokhttg

zvokhttg1#

上一个查询中的逻辑是正确的,只是需要将select *替换为select l.ProductID, i.CustomerID(否则将出现“重复列名”错误):

SELECT *
FROM Customers AS C
WHERE NOT EXISTS
(
    SELECT *
    FROM Products AS P
    WHERE NOT EXISTS
    (
        SELECT *
        FROM 
            (
            SELECT L.ProductID, I.CustomerID
            FROM InvoiceLines AS L
            JOIN Invoices AS I ON L.InvoiceID = I.InvoiceID
            ) AS Pu
        WHERE Pu.CustomerID = C.CustomerID
        AND Pu.ProductID = P.ProductID
    )
)
qacovj5a

qacovj5a2#

解决此问题时需要关注的两个主要列是发票和发票行中的CustomerID和ProductID,其他表仅在您获得结果后返回附加列,结果是计数(非重复L.ProductID)等于计数(P.ProductID)的I.CustomerId集。

相关问题