【问题标题】:How would you construct this SQL query? (MySQL)你将如何构造这个 SQL 查询? (MySQL)
【发布时间】:2011-12-23 20:56:54
【问题描述】:

假设我们有这些表:

产品

product_id
product_name

类别

category_id
category_name

product_in_category

​​>
product_in_category_id
product_id
category_id

如何获得 product_in_category 表中不属于特定类别的所有产品(没有重复项)。

换句话说,例如,所有未分配到类别 10 的产品。 此外,如果一种产品属于类别 1、5 和 10,则它不应该出现在结果中。

【问题讨论】:

  • 当您提到“类别 1、5 和 10”时,您是指所有,还是至少其中一个?

标签: sql mysql


【解决方案1】:

使用 LEFT JOIN/IS NULL:

   SELECT p.*
     FROM PRODUCT p
LEFT JOIN PRODUCT_IN_CATEGORY pic ON pic.product_id = p.product_id
                                 AND pic.category_id = 10
    WHERE pic.product_in_category_id IS NULL

使用 NOT IN

SELECT p.*
  FROM PRODUCT p
 WHERE p.product_id NOT IN (SELECT pic.product_id
                              FROM PRODUCT_IN_CATEGORY pic
                             WHERE pic.category_id = 10)

使用不存在

SELECT p.*
  FROM PRODUCT p
 WHERE NOT EXISTS (SELECT NULL
                     FROM PRODUCT_IN_CATEGORY pic
                    WHERE pic.product_id = p.product_id
                      AND pic.category_id = 10)

哪个最好?

这取决于被比较的列是否可以为空(值可以为 NULL)。如果他们是nullable, then NOT IN/NOT EXISTS are more efficient。如果列是not nullable, then LEFT JOIN/IS NULL is more efficient (MySQL only)

【讨论】:

    【解决方案2】:
    SELECT * FROM product_in_category WHERE category_id!=10
    

    还是我错过了什么?我想我错过了没有重复的部分,看看 InSane 的更好答案。

    【讨论】:

    • 是的,我意识到,在我写完之后,InSane 已经提出了一个更好的解决方案,无论如何。
    【解决方案3】:
    SELECT product_id FROM product
    LEFT OUTER JOIN product_in_category
    ON product.product_id = product_in_category.product_id
    WHERE product_in_category.product_id IS NULL
    GROUP BY product_id
    

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 2023-03-03
      • 2013-02-19
      • 2023-03-22
      相关资源
      最近更新 更多