【问题标题】:SQL query with subquery using NOT operator使用 NOT 运算符的带有子查询的 SQL 查询
【发布时间】:2019-06-10 00:22:38
【问题描述】:

新手在这里使用W3schools demo database 练习 SQL 查询,但我被困在一个:

SELECT Customers.CustomerID, Customers.CustomerName, Orders.OrderID, OrderDetails.ProductID, Products.ProductName FROM Customers
INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
INNER JOIN OrderDetails ON OrderDetails.OrderID = Orders.OrderID
INNER JOIN Products ON Products.ProductID = OrderDetails.ProductID
WHERE OrderDetails.ProductID <> 70

我想查看已下订单但尚未订购产品 ID 70 的客户列表。

此查询仍然显示订购产品 ID 为 70 的客户的其他订单。如果客户已订购,我不想在此列表中看到他们的任何其他订单。这种情况是否需要使用 WHERE EXISTS 的子查询?

谢谢!

【问题讨论】:

    标签: sql


    【解决方案1】:

    使用聚合:

    SELECT c.CustomerID, c.CustomerName
    FROM Customers c JOIN
         Orders o
         ON c.CustomerID = o.CustomerID JOIN
         OrderDetails od
         ON od.OrderID = o.OrderID
    GROUP BY c.CustomerID, c.CustomerName
    HAVING SUM(CASE WHEN od.ProductID = 70 THEN 1 ELSE 0 END) = 0;
    

    这是一个与询问哪些订单有产品 70 不同的问题。只需查看一行以查看产品是否存在即可回答该问题。但是,要确定产品 70 是否按任何顺序,您需要查看所有这些,这就是需要聚合的原因。

    【讨论】:

      【解决方案2】:

      听起来您只是在寻找 NOT 关键字:

      SELECT Customers.CustomerID, Customers.CustomerName, Orders.OrderID, OrderDetails.ProductID, Products.ProductName FROM Customers
      INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
      INNER JOIN OrderDetails ON OrderDetails.OrderID = Orders.OrderID
      INNER JOIN Products ON Products.ProductID = OrderDetails.ProductID
      WHERE NOT OrderDetails.ProductID = 70
      

      【讨论】:

      • NOT OrderDetails.ProductID = 70OrderDetails.ProductID &lt;&gt; 70 完全一样
      • 这会产生相同的结果,这不是我想要的。
      【解决方案3】:

      您确实可以为此使用 NOT EXSISTS 查询:

      SELECT c.*
      FROM customers c
      WHERE NOT EXISTS (select *
                        from orders o
                          join orderdetails od on o.orderid = od.orderid
                        where o.customerid = c.customerid
                          and od.productid = 70);
      

      子查询测试每个客户是否至少有一个 productid = 70 的订单。如果不存在这样的订单,NOT EXISTS 将导致“真”,从而将该客户包括在整体结果中。

      由于您只需要客户列表,因此无需将订单表连接到主查询中。

      【讨论】:

      • 谢谢,这也可以,但它会显示所有客户,包括没有订购任何东西的客户。我编辑了我的问题,以进一步澄清该查询是针对已下订单的客户。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2020-10-29
      相关资源
      最近更新 更多