I have two tables at my DB that i want to make a select query First one keeps the product id (int) and if the product is published The second table keeps the filters, and matches with id_product (which is basicaly the product_id from Products) . at id_filter_child we have the value
products
product_id,
published
filters
id_pro_fil,
id_product,
id_filter_child
My tables now are:
products
1 yes
2 yes
3 no
filters
10 1 4
11 1 5
12 2 4
13 2 6
14 2 7
So that is my DB at the moment. From input i have the filters that i want to search So i want to select all products with filter=4 i use:
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child='4'
That one works!
Now i need to select all products with filter 4 AND 6. I use:
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child='4'
AND filters.id_filter_child='6'
but i doesnt work (as a result i would want the product with id=2)
Some help please
Thanks in advance
Try this:
SELECT p.*
FROM products p
LEFT JOIN filters ON p.product_id = f.id_product
WHERE p.published='1' AND f.id_pro_fil IN (4,6)
Consider your logic:
AND filters.id_filter_child='4'
AND filters.id_filter_child='6'
You're requiring every filter_child
in the database to have two DIFFERENT values at the same time. "this record must be a banana and a ferrari simutaneously"
You want an OR
instead:
AND ((filter_child = '4') OR (filter_child = '6'))
(note the extra brackets), or more compactly:
AND (filter_child IN ('4', '6'))
--- comment followup
If you need both values to be attached to a record,t hen you'll have to use some extra logic:
SELECT *, COUNT(filters.id_filter_child IN ('4', '6')) AS count
FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child IN ('4', '6')
GROUP BY filters.id_filter_child
HAVING count = 2
The where
returns only the records that have either 4
or 6
for filter_child - this will catch records that have at least ONE of those two values. The COUNT(..)
+ GROUP
+ HAVING
business will then filter out all but those records that have BOTH of the values.
You can use OR or IN
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND (filters.id_filter_child='4' OR filters.id_filter_child='6')
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child IN (4,6)
you should OR in between the two conditions:
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child='4'
OR filters.id_filter_child='6'
but to make your sql smaller and simpler you can use IN operator also:
SELECT * FROM products,filters
WHERE products.product_id=filters.id_product
AND products.published='1'
AND filters.id_filter_child IN(4,6)
If you want to select all products, then there is no reason to also include the filters. One approach is to use an aggregation and having
clause:
SELECT p.*
FROM products p JOIN
filters f
ON p.product_id = f.id_product
WHERE p.published = '1'
GROUP BY p.product_id
HAVING SUM(f.id_filter_child = '4') > 0 AND
SUM(r.id_filter_child = '6') > 0
This returns product that have both filter 4 and filter 6.
Note that I also fixed the query to use proper, explicit join
syntax.
I like this method for "set-within-sets" subqueries, because it is quite general. You can add another filter to the HAVING
clause with a similar condition. You could get everything with 4 but not 6 by changing the second > 0
to = 0
.
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.