Esta pregunta se deriva de MYSQL join results set wiped results during IN() in where clause?dividir una cadena en MySQL del GROUP_CONCAT en un (array, como, una expresión, lista) que, en() puede comprender
Así, versión corta de la cuestión. ¿Cómo se puede convertir la cadena devuelta por GROUP_CONCAT en una lista de expresiones separadas por comas que IN() tratará como una lista de múltiples elementos para repetir?
N.B. Los documentos MySQL parecen referirse al "(coma, separado, listas)" usado por IN() como 'listas de expresiones', y curiosamente las páginas en IN() parecen ser más o menos las únicas páginas en los documentos MySQL para alguna vez consulte las listas de expresiones Así que no estoy seguro de si las funciones destinadas a crear matrices o tablas temporales serían útiles aquí.
versión basada en ejemplos largo de la pregunta: ¿A partir de una 2-mesa de DB como esto:
SELECT id, name, GROUP_CONCAT(tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id GROUP BY person.id;
+----+------+----------------------+
| id | name | GROUP_CONCAT(tag_id) |
+----+------+----------------------+
| 1 | Bob | 1,2 |
| 2 | Jill | 2,3 |
+----+------+----------------------+
¿Cómo puedo convertir este, que ya que utiliza una cadena se trata como equivalente lógico de (1 = X) y (2) = X ...
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.01 sec)
... en algo donde el resultado GROUP_CONCAT se trata como una lista, de modo que para Bob, que sería equivalente a:
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id AND person.id = 1
GROUP BY person.id HAVING ((1 IN (1,2)) AND (2 IN (1,2)));
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Bob | 1,2 |
+------+--------------------------+
1 row in set (0.00 sec)
... y para Jill, sería equivalente a:
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id AND person.id = 2
GROUP BY person.id HAVING ((1 IN (2,3)) AND (2 IN (2,3)));
Empty set (0.00 sec)
... por lo que el resultado global sería una cláusula de búsqueda exclusiva que requiere todas las etiquetas que figuran que no utiliza HAVING COUNT (DISTINTO ...) ?
(nota: Esta lógica funciona sin la Y, aplicando al primer carácter de la cadena, por ejemplo
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id
GROUP BY person.id HAVING ((2 IN (GROUP_CONCAT(tag.tag_id))));
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Jill | 2,3 |
+------+--------------------------+
1 row in set (0.00 sec)
Esto es agradable, pero vale la pena señalar que no es necesario hacer el 'GROUP_CONCAT()' 'en todo el FIND_IN_SET()'. Puedes simplemente 'SELECCIONAR GROUP_CONCAT (tag.tag_id) AS tags_list' y luego' HAVING FIND_IN_SET (20, tags_list) ' – Treffynnon