Я хотел сделать запрос с помощью Rails, что-то вроде этого:
filters = Filter.joins(:category_filters).where("category_id IN (?)", params[:categories]).group("filters.id")
И заявление MySQL, которое делает это:
SELECT `filters`.* FROM `filters` INNER JOIN `category_filters` ON `category_filters`.`filter_id` = `filters`.`id` WHERE (category_id IN ('9,4')) GROUP BY filters.id
На первый взгляд, этот запрос в порядке, но когда я смотрю результаты, он ошибается. Позвольте мне объяснить вам.
Во-первых, это запрос к таблице фильтров:
select * from filters;
+----+----------+-------+----------+------------+------------+
| id | name | other | optional | created_at | updated_at |
+----+----------+-------+----------+------------+------------+
| 1 | material | 1 | 1 | NULL | NULL |
| 2 | abc | 1 | 0 | NULL | NULL |
| 3 | xyz | 0 | 0 | NULL | NULL |
| 4 | 123a | 0 | 0 | NULL | NULL |
+----+----------+-------+----------+------------+------------+
Во-вторых, это запрос к таблице category_filters:
select * from category_filters;
+----+-----------+-------------+------------+------------+
| id | filter_id | category_id | created_at | updated_at |
+----+-----------+-------------+------------+------------+
| 1 | 1 | 1 | NULL | NULL |
| 2 | 2 | 1 | NULL | NULL |
| 3 | 1 | 9 | NULL | NULL |
| 4 | 2 | 9 | NULL | NULL |
| 5 | 1 | 4 | NULL | NULL |
| 6 | 3 | 4 | NULL | NULL |
+----+-----------+-------------+------------+------------+
А теперь запрос, сгенерированный Rails (первый запрос):
SELECT `filters`.* FROM `filters` INNER JOIN `category_filters` ON `category_filters`.`filter_id` = `filters`.`id` WHERE (category_id IN ('9,4')) GROUP BY filters.id;
+----+----------+-------+----------+------------+------------+
| id | name | other | optional | created_at | updated_at |
+----+----------+-------+----------+------------+------------+
| 1 | material | 1 | 1 | NULL | NULL |
| 2 | abc | 1 | 0 | NULL | NULL |
+----+----------+-------+----------+------------+------------+
Почему это происходит?
Но теперь, это аналогичный запрос, вместо использования IN я использовал ИЛИ, например:
SELECT `filters`.* FROM `filters` INNER JOIN `category_filters` ON `category_filters`.`filter_id` = `filters`.`id` WHERE (category_filters.category_id=9 or category_filters.category_id=4) GROUP BY filters.id;
+----+----------+-------+----------+------------+------------+
| id | name | other | optional | created_at | updated_at |
+----+----------+-------+----------+------------+------------+
| 1 | material | 1 | 1 | NULL | NULL |
| 2 | abc | 1 | 0 | NULL | NULL |
| 3 | xyz | 0 | 0 | NULL | NULL |
+----+----------+-------+----------+------------+------------+
Что происходит?