简体   繁体   中英

How to select rows, which have all or none corresponding values in another table?

I'm not sure I phrased the question correctly, so feel free to correct me. Here are the tables with their data:

product        category                 category_product
-------        --------                 ----------------
id_product     id_category  active      id_category  id_product
1              1            1           1            1
2              2            1           2            1
3              3            0           1            2
               4            0           2            2
                                        3            2
                                        3            3
                                        4            3

I need to select only those products, which have all categories as inactive. For example:

  • Product 1 is good, since it belongs to active categories ( 1 , 2 ).
  • Product 2 is good, since it has at least one active category ( 1 , 2 ; 3 - inactive)
  • Product 3 must be selected, since all its categories are inactive ( 3 , 4 ).

I have the following query, which is obviously incorrect, since it selects both products: 2 and 3 :

SELECT p.id_product
FROM product p
JOIN category_product cp
  ON p.id_product = cp.id_product
JOIN category c
  ON c.id_category = cp.id_category
WHERE
  c.active = 0;

Here is the SQL Fiddle: http://sqlfiddle.com/#!2/909dd/2/0

How can I solve this?

This way you can select product without active category.

SELECT p.id_product
FROM product p
WHERE NOT EXISTS     
    (SELECT * FROM 
     category_product cp  
     INNER JOIN category c ON c.id_category = cp.id_category
     WHERE p.id_product = cp.id_product AND c.active = 1);

SQL Fiddle

This is what i get while trying...apologies if anything is wrong

set @count:=0;
select a.id_product,a.times from 
    (SELECT    count(p.id_product)times, p.id_product, c.active, 
               if(c.active!=0, @count:=@count+1, @count:=0) x
    From category_product cp
         join  product p
               on (p.id_product = cp.id_product)
        join   category c
               on(c.id_category = cp.id_category )
    group by id_product )a 
where a.x=0;

Consider the following:

SELECT p.* 
     , COUNT(*)
     , SUM(c.active = 1) active
     , SUM(c.active = 0) inactive
  FROM product p
  JOIN category_product cp 
    ON cp.id_product = p.id_product
  JOIN category c
    ON c.id_category = cp.id_category
 GROUP
    BY p.id_product;

+------------+----------+--------+----------+
| id_product | COUNT(*) | active | inactive |
+------------+----------+--------+----------+
|          1 |        2 |      2 |        0 |
|          2 |        3 |      2 |        1 |
|          3 |        2 |      0 |        2 |
+------------+----------+--------+----------+

http://sqlfiddle.com/#!2/909dd/55

The last part of this problem has been left as an exercise for the reader

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