Question

I am experimenting with a faceted search using MySql.

I have two tables:

accessories:

id    product_id    price

1     6000001       24.99
2     6000002       20.99
3     6000003       22.99
4     6000004       25.99
5     6000005       29.99

tags:

id    tagname    tagid    tagvalue    product_id

1     Brand     6000008   Apple       6000001
2     Colour    6000009   Green       6000001
3     Brand     6000008   Sony        6000003
4     Brand     6000008   Sharp       6000021
5     Brand     6000008   Panasonic   6000022
6     Brand     6000008   Onkyo       6000027

Currently I am running the follwing query to select a list of products:

SELECT 
tags.tagname, 
tags.tagid, 
tags.tagvalue, 
accessories.* 
FROM accessories 
Left Join tags ON tags.product_id = accessories.product_id 
WHERE tags.tagid = '6000008'

The join gives a recordset containing 6 records.

To populate the facets of my search, I also want a list of [tags.tagvalues] where [accessories.product_id] and [tags.product_id] match, as well as preserving the above query.

So I would need to return "Apple" and "Green" as well as the 6 records.

I could fire off a query for each product_id, but this seems a very ineficient method. Perhaps my methodology needs a re-think.

Was it helpful?

Solution

If I understand correctly, you want all tags for products that have a tag matching tags.tagid = '6000008'. Logically, you can get this as:

SELECT tags.tagname, tags.tagid, tags.tagvalue, accessories.* 
FROM accessories left join
     tags
     ON tags.product_id = accessories.product_id 
WHERE accessories.product_id in (select product_id
                                 from tags
                                 where tags.tagid = '6000008'
                                )

Earlier versions of MySQL had performance problems with in and subqueries. You can rewrite this as a join:

SELECT tags.tagname, tags.tagid, tags.tagvalue, accessories.* 
FROM accessories left join
     tags
     ON tags.product_id = accessories.product_id join
     (select distinct product_id
      from tags
      where tags.tagid = '6000008'
     ) Filter
     on accesories.Product_id = Filter.Product_id
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top