Сильно отредактировано!
Исходный вопрос был основан на неправильном понимании того, как IN () обрабатывает столбец из набора результатов из объединения.Я думал, что IN (some_join.some_column) будет обрабатывать столбец результатов как список и проходить по каждой строке на месте.Оказывается, это выглядит только в первом ряду.
Итак, адаптированный вопрос: есть ли в MySQL что-нибудь, что может циклически проходить через столбец результатов из объединения из предложения WHERE?
Вот супер упрощенный код, с которым я работаю, урезанный от сложной функции поиска CRM.Левое объединение и общая идея - это остатки этого запроса.Так что для этого запроса это должен быть эксклюзивный поиск - поиск людей со ВСЕМИ указанными тегами, а не только с любыми.
Сначала БД
Таблица 1: Персона
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Jill |
+----+------+
Таблица 2: Метка
+-----------+--------+
| person_id | tag_id |
+-----------+--------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 3 |
+-----------+--------+
Красиво и просто.Итак, естественно:
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id GROUP BY name;
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Bob | 1,2 |
| Jill | 2,3 |
+------+--------------------------+
Пока все хорошо.Так что я ищу то, что бы найти только Боба в первом случае и только Джилл во втором - без использования HAVING COUNT (DISTINCT ...), потому что это не работает в более широком запросе (есть отдельные тегиКэш наследования и куча других вещей).
Вот мои оригинальные примеры запросов - основанные на ложной идее, что IN () будет циклически проходить по всем строкам одновременно.
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE ( ( 1 IN (tag.tag_id) ) AND ( 2 IN (tag.tag_id) ) );
Empty set (0.00 sec)
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE ( ( 2 IN (tag.tag_id) ) AND ( 3 IN (tag.tag_id) ) );
Empty set (0.00 sec)
Вот мойновая последняя неудачная попытка дать представление о том, к чему я стремлюсь ...
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id
GROUP BY person.id HAVING ( ( 1 IN (GROUP_CONCAT(tag.tag_id) ) ) ) AND ( 2 IN (GROUP_CONCAT(tag.tag_id)) );
Empty set (0.00 sec)
Так что, похоже, он принимает строку GROUP_CONCAT, либо 1,2, либо 2,3, и обрабатывает еекак единое целое, а не список выражений.Есть ли способ превратить сгруппированный столбец в список выражений, который IN () или = ANY () будет обрабатывать как список?
По сути, я пытаюсь сделать цикл IN () итеративно над чем-то, чтонапоминает массив или список динамических выражений, который содержит все строки данных, которые поступают из объединения.