Проблема SQL, LEFT JOIN [..] IN()
Эта маленькая ошибка SQL беспокоит меня. Похоже, что это не проблема с запросом, только область (?), Примеры лучше всего работают:
SELECT ocp.*, oc.*, GROUP_CONCAT( u.username SEPARATOR ', ') AS `memjoined`
FROM gangs_ocs_process ocp, gangs_ocs oc
LEFT JOIN users u ON u.userid IN ( ocp.membersin )
WHERE ocp.ocid =1 AND ocp.gangid =1 AND oc.oc_name = ocp.crimename
GROUP BY ocp.ocid
LIMIT 0 , 30
Theres столбец (gangs_ocs_process.membersin), который имеет список идентификаторов, которые присоединились (то есть 1,2,5). Я пытаюсь получить имена пользователей для каждого из этих идентификаторов (из users
таблица) за один раз.
Проблема в LEFT JOIN users u ON u.userid IN ( ocp.membersin )
Если я заменю 1,2,4
в течение ocp.membersin
(помещая буквенный список вместо имени столбца), все работает нормально. Возвращает столбец с именами пользователей ( изображение). Однако, если я уйду в ocp.membersin, я получу эту ошибку:
#1054 - Unknown column 'ocp.membersin' in 'on clause'
Я впервые использую IN в левом соединении, поэтому я немного растерялся.
Любая помощь будет отличной:)
6 ответов
Я не думаю, что "IN" будет работать для этого синтаксиса. MySQL ожидает, что IN будет чем-то похожим на набор данных, а не на строку с разделителями. Я думаю, что вам нужно найти способ принять участников, расширить его до набора данных, с которым может работать MySQL (может быть, временная таблица), и присоединиться к нему.
Если у вас есть строки с разделителями в вашей таблице, у вас есть проблема дизайна в вашей базе данных. Добавьте новую таблицу для хранения этих значений.
Причина, по которой вы не можете заставить его работать, заключается в том, что сначала вам нужно нормализовать базу данных. Вы НИКОГДА не должны, НИКОГДА не иметь список идентификаторов в одном столбце.
Вы уверены, что "membersin" находится в таблице "gangs_ocs_process", а не в таблице "gangs_ocs"?
Это плохой способ сохранить членство.
Но если вам все еще нужно жить с этим, вы можете попробовать REGEXP
соответствие для проверки на членство:
SELECT ocp.*, oc.*, GROUP_CONCAT( u.username SEPARATOR ', ') AS `memjoined`
FROM gangs_ocs_process ocp
LEFT JOIN users u ON (ocp.membersin RLIKE CONCAT('(^|,)[[:blank:]]?', userid, '[[:blank:]]?($|,)'))
JOIN gangs_ocs oc ON (ocp.ocid = 1 AND ocp.gangid = 1 AND oc.oc_name = ocp.crimename)
GROUP BY ocp.ocid
LIMIT 0 , 30
После еще одного взгляда я думаю, что ваша проблема заключается в том, что вы пытаетесь агрегировать не в той точке, а также в синтаксисе IN, и что вы должны агрегировать в подзапросе, ограниченном содержимым IN. Я не знаю достаточно о вашей схеме, чтобы все было правильно, но вы хотите что-то подобное. SomeKeyfield должен относиться обратно к gangs_ocs_process
SELECT ocp.*, oc.*, u.Memjoined
FROM gangs_ocs_process ocp, gangs_ocs oc
LEFT JOIN (Select SomeKeyField, GROUP_CONCAT( u.username SEPARATOR ', ') as memjoined
from users where userid in
(select membersin from gangs_ocs_process
where [whatever conditions] )
Group By SomeKeyField) u on ocp.SomeKeyField = u.SomeKeyField
WHERE ocp.ocid =1 AND ocp.gangid =1 AND oc.oc_name = ocp.crimename
GROUP BY ocp.ocid
LIMIT 0 , 30