Mysql - 查询关系,树结构和条件

时间:2017-01-11 09:40:52

标签: mysql sql

我的MySql查询有问题。我有三张桌子

product table
+----+------------------------------------------------------+
| id | title                                                |
+----+------------------------------------------------------+
|  1 | title1                                               |
|  2 | title2                                               |
|  3 | title3                                               |
+----+------------------------------------------------------+

category table
+----+-------+--------+
| id | path  | name   |
+----+-------+--------+
| 1  | 1     | title1 |
| 2  | 1/2   | title2 |
| 3  | 1/2/3 | title3 |
| 4  | 1/4   | title4 |
| 5  | 5     | title5 |
| 6  | 5/6   | title6 |
| 7  | 7     | title7 |
| 8  | 7/8   | title8 |
| 9  | 7/9   | title9 |
+----+-------+--------+

category_product table
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1          | 3           |
| 1          | 6           |
| 2          | 2           |
| 3          | 6           |
+------------+-------------+

现在,我想选择存储在类别1及其子类别和5及其子类别中的那些产品的产品名称。我有这些想法,

第一个想法:

SELECT 
  product_name
FROM 
  product
WHERE
  id IN SELECT(id FROM product_category WHERE category_id = 1 OR path LIKE "1/%")
  AND id IN SELECT(id FROM product_category WHERE category_id = 5 OR path LIKE "5/%")

对于更多类别的条件,这里可能有许多子选择。

第二个想法:

SELECT 
  product_name
FROM 
  product p
  INNER JOIN product_category AS prdcat1 ON (prdcat1.product_id = p.id)
  INNER JOIN category AS cat1 ON (cat1.id = prdcat1.category_id AND cat1.id = 1 OR cat1.path LIKE "1/%")
  INNER JOIN product_category AS prdcat2 ON (prdcat2.product_id = p.id)
  INNER JOIN category AS cat2 ON (cat2.id = prdcat2.category_id AND cat2.id = 5 OR cat2.path LIKE "5/%")

可能有很多JOIN - 更多的MySql限制了连接表的nubmer。

第三个想法:

SELECT
  product_name
FROM
  product p
  INNER JOIN category_product cp ON (p.id = cp.product_id)
  INNER JOIN category c ON (cp.category_id = c.id)
GROUP BY
  product_id
HAVING 
  (GROUP_CONCAT(c.path) LIKE "1,%" OR GROUP_CONCAT(c.path) LIKE "%,1,%" OR GROUP_CONCAT(c.path) LIKE "%,1/%")
  AND (GROUP_CONCAT(c.path) LIKE "5,%" OR GROUP_CONCAT(c.path) LIKE "%,5,%" OR GROUP_CONCAT(c.path) LIKE "%,5/%");

GROUP_CONAT限制如此。

这三种方法都很丑陋,可能很慢。你的意思是什么?是否有任何一般推荐的方法来解决这种情况?对不起,如果已存在类似问题 - 我不知道该怎么问。感谢。

0 个答案:

没有答案