One product in many categories - PHP MySQL
I have a table products
开发者_如何学Go(id, barcode, catid, name, description, ...) and I've been asked to make it possible that some products can be assigned to more than one categories.
The most obvious solution would be to change catid from INT to VARCHAR with delimited values ie 1,2,5 where 1,2 & 5 are the various categories.
Which SQL statement will do the job for me now? I have find_in_set in mind but I think it does the opposite.
The most obvious solution would be to create a 'cross-table' where you can do a many-to-many assignment (as in one category can have many products and one product can have many categories). This table would look like this:
product_id | category_id
You can then use this query:
SELECT
*
FROM
(product JOIN product_has_category ON product.id = product_has_category.product_id)
JOIN category ON product_has_category.category_id = category.id
You can even use normal WHERE
and `ORDER BY, etc.
edit: Fixed a major error in my query, my appologies!
If you are unable to change the database, you might want to try this:
SELECT
*
FROM
category, product
WHERE
product.id = ?? AND FIND_IN_SET(category.id, product.catid) > 0 GROUP BY product.id
Warning: It is a long shot, I haven't tested this, but as FIND_IN_SET would search a comma-seperated list, it could work.
Don't delimit your category ideas in a single field. You're setting yourself up for much pain. Use a many to many relationship.
products:
id,
barcode
...
category:
cat_id,
cat_name
product_category:
product_id
cat_id
To get all products in a particular category:
SELECT * FROM products JOIN product_category ON product_id=id WHERE cat_id=?
To get all categories for a product
SELECT * FROM category JOIN product_category ON product_category.cat_id = category.cat_id WHERE product_id=?
Your best bet would be to have a separate table with 'categories' and entries for each product. Normalize it this way.
If you don't want to do that, use a bitmask. Its much easier than parsing a comma delimited list of entries.
drop the catid and use a table that associates the id to one catid per row (cross-table).
I'd suggest the better solution would be to have a second table that maps product ids to categories, with an entry for each category that matches a product. It makes querying categories a little more complex by having to use JOIN, but is a more relational-database way than having a field with delimited values within the same table, which sounds like a nightmare to write queries for.
精彩评论