Вопрос

Эта небольшая ошибка 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 

Есть столбец (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 в левых соединениях, так что я немного растерялся.

Любая помощь была бы замечательной :)

Это было полезно?

Решение

Я не думаю, что "IN" будет работать для этого синтаксиса.MySQL ожидает, что IN будет чем-то похожим на dataset, а не на строку с разделителями.Я думаю, вам нужно найти способ взять membersin, развернуть его в набор данных, с которым MySQL может работать (возможно, временную таблицу), и присоединиться к нему.

Другие советы

Если у вас в таблице есть строки с разделителями, значит, у вас проблема с дизайном в вашей базе данных.Добавьте новую таблицу для хранения этих значений.

Вы уверены, что 'membersin' находится в таблице 'gangs_ocs_process', а не в таблице 'gangs_ocs'?

Причина, по которой вы не можете заставить это работать, заключается в том, что сначала вам нужно привести вашу базу данных в НОРМУ.У вас НИКОГДА не должно быть списка идентификаторов в одном столбце.

Взглянув еще раз, я думаю, что ваша проблема заключается в попытке агрегирования в неправильной точке, а также в синтаксисе 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

Это такой плохой способ чтобы сохранить членство.

Но если вам все еще нужно жить с этим, вы можете попробовать 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top