简体   繁体   中英

SQL 'Not in' query involving three tables

I have three tables, product, category and product_to_category. Product has the primary key product_id, category category_id and product_to_category p2c_id. Product_to_ category links products to categories in a many-to-many relationship using their respective ID's.

Basically I want to write a query that would select all products from categories that do not exist in the category table. This is due to products being migrated across from another database.

I had something like this but was a little lost.

SELECT * 
FROM product AS p 
LEFT JOIN product_to_category AS p2c ON p.product_id = p2c.product_id 
LEFT JOIN category AS c ON c.category_id 

Basically that is as far as I have got. I need to join the category table to the product_to_category table where the product_to_category category_id is not in the category table. I may be completely on the wrong path but am stuck! Thanks in advance.

If you're looking for products from nonexistent categories, I'd suggest

Select p.*,p2c.category_id
  from product p
  join product_to_category p2c
    on p.product_id=p2c.product_id
  left outer join category c
    on p2c.category_id=c.category_id
where c.category_id is null
   SELECT p.*
     FROM product AS p
LEFT JOIN product_to_category AS p2c ON p.product_id = p2c.product_id
    WHERE NOT EXISTS (
          SELECT 1
            FROM category c
           WHERE c.category_id = p2c.category_id
    )

Assumption: A product can be part of categories that exist, categories that do not exist, or no categories at all. You have not asked for products that belong to no categories at all, so the first LEFT JOIN from product to procduct_to_category should be an INNER JOIN.

Caveat: I am rusty at mysql so I am using SQL SERVER syntax. I forget if mysql has ON clauses or uses where clauses for JOINs. If ON clause is not supported, change them into WHERE clauses.

There are two common approaches: OUTER JOIN or a NOT IN clause (or a NOT EXISTS clause, which often behaves the same performance-wise as the NOT IN clause.)

  1. OUTER JOIN

    select p.*, p2c.category_id

    from product p

    INNER JOIN product_to_category p2c ON (p.product_id = p2c.product_id)

    LEFT JOIN category c ON p2c.category_id = c.category_id

    WHERE c.category_id IS NULL

The test for null will find the unmatched records.

  1. NOT IN clause

    SELECT p.*, p2c.category_id

    FROM product p

    INNER JOIN product_to_category p2c ON (p.product_id = p2c.product_id)

    WHERE p2c.category_id NOT IN (SELECT c.category_id FROM category c)

SELECT * 
FROM product AS p 
JOIN product_to_category AS p2c ON p.product_id = p2c.product_id  
JOIN category AS c ON c.category_id != as.category.

Try this?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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