我有3张桌子:
类型
+----+-------------+-----------------------+------------+------------+
| id | category_id | name | created_at | updated_at |
+----+-------------+-----------------------+------------+------------+
| 1 | 1 | T-Shirts | NULL | NULL |
+----+-------------+-----------------------+------------+------------+
原型
+----+-----------------------------------------+------------+------------+
| id | name | created_at | updated_at |
+----+-----------------------------------------+------------+------------+
| 1 | Gildan Softstyle Adult Ringspun T-shirt | NULL | NULL |
+----+-----------------------------------------+------------+------------+
过滤器
+----+-------------+---------------------+-------+------------+------------+
| id | name | value | extra | created_at | updated_at |
+----+-------------+---------------------+-------+------------+------------+
| 1 | gender | male | NULL | NULL | NULL |
| 2 | gender | female | NULL | NULL | NULL |
| 3 | age_group | adult | NULL | NULL | NULL |
| 4 | age_group | child | NULL | NULL | NULL |
| 5 | age_group | baby | NULL | NULL | NULL |
+----+-------------+---------------------+-------+------------+------------+
它们通过n-m关系彼此相关,因此也有相应的联结表types_prototypes
,types_filters
,prototypes_filters
。有关详细信息,请查看我的dump file。
我正在尝试设置过滤系统(使用Laravel),因此我需要查询与所有给定过滤器相关的所有原型(逻辑< strong>和)。到目前为止,我已经设法获得了,只要使用只选择了一个过滤器:
select * from `prototypes`
inner join `types_prototypes` on `prototypes`.`id` = `types_prototypes`.`prototype_id`
inner join `prototypes_filters` on `prototypes`.`id` = `prototypes_filters`.`prototype_id`
inner join `filters` on `prototypes_filters`.`filter_id` = `filters`.`id`
where `types_prototypes`.`type_id` = ? and `filter_id` = ? group by `prototypes`.`id`
问题本身在于,只要我们有多个同时有效的过滤器,此查询就不适用:
...
where `types_prototypes`.`type_id` = ? and `filter_id` = ? and `filter_id` = ? group by `prototypes`.`id`
我知道,where ... and
无效,因为我只有一列filter_id
只能同时包含一个值(实际上是groupBy()
照顾)。因此,在这个意义上,我有一个新的行,用于相同的原型与另一个过滤器的关系,例如:
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
| id | name | created_at | updated_at | type_id | prototype_id | prototype_id | filter_id | id | name | value | extra | created_at | updated_at |
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
| 1 | Gildan Softstyle Adult Ringspun T-shirt | NULL | NULL | 1 | 1 | 1 | 1 | 1 | gender | male | NULL | NULL | NULL |
| 1 | Gildan Softstyle Adult Ringspun T-shirt | NULL | NULL | 1 | 1 | 1 | 3 | 3 | age_group | adult | NULL | NULL | NULL |
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
我已经尝试了几种不同的方法,包括where 'filter_id' in(?,?)
,where FIND_IN_SET('filter_id', '?,?')
,甚至根据 EAV-pattern 重新构建了我的数据库(当filters
是分为filter_names
和filter_values
)。但每次我只获得满足整个集合的一个要求的条目(例如,等于逻辑 OR )(这里我们有成人的原型 和 男性,但不仅>> 成年男性):
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
| id | name | created_at | updated_at | type_id | prototype_id | prototype_id | filter_id | id | name | value | extra | created_at | updated_at |
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
| 1 | Gildan Softstyle Adult Ringspun T-shirt | NULL | NULL | 1 | 1 | 1 | 1 | 1 | gender | male | NULL | NULL | NULL |
| 2 | American Apparel Womans T-Shirt | NULL | NULL | 1 | 2 | 2 | 3 | 3 | age_group | adult | NULL | NULL | NULL |
| 3 | Gildan Adult Cotton T-shirt | NULL | NULL | 1 | 3 | 3 | 1 | 1 | gender | male | NULL | NULL | NULL |
| 4 | American Apparel Mens T-Shirt | NULL | NULL | 1 | 4 | 4 | 1 | 1 | gender | male | NULL | NULL | NULL |
| 5 | American Apparel Kids T-Shirt | NULL | NULL | 1 | 5 | 5 | 1 | 1 | gender | male | NULL | NULL | NULL |
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+
我几乎绝望了,有人有线索吗? 感谢您的建议,感谢您的帮助,对于这么多文本感到抱歉,我只是想描述所有情况。
答案 0 :(得分:3)
您必须为每个条件重复加入过滤器表。
select * from prototypes AS p
inner join types_prototypes AS tp1 on p.id = tp1.prototype_id
inner join prototypes_filters AS pf1 on p.id = pf1.prototype_id
inner join filters AS f1 on pf1.filter_id = f1.id
inner join types_prototypes AS tp2 on p.id = tp2.prototype_id
inner join prototypes_filters AS pf2 on p.id = pf2.prototype_id
inner join filters AS f2 on pf2.filter_id = f2.id
where tp1.type_id = ? and f1.filter_id = ?
AND tp2.type_id = ? and f2.filter_id = ?
group by prototypes.id