WHERE AND子句用于同一列但不同的行

时间:2017-04-12 20:05:07

标签: mysql sql join

事先信息通知

我有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_prototypestypes_filtersprototypes_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_namesfilter_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       |
+----+-----------------------------------------+------------+------------+---------+--------------+--------------+-----------+----+-----------+-------+-------+------------+------------+

我几乎绝望了,有人有线索吗? 感谢您的建议,感谢您的帮助,对于这么多文本感到抱歉,我只是想描述所有情况。

1 个答案:

答案 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