Проблема SQL, LEFT JOIN [..] IN () - PullRequest
       27

Проблема SQL, LEFT JOIN [..] IN ()

0 голосов
/ 20 февраля 2009

Эта маленькая ошибка 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 (поместив буквенный список вместо имени столбца), все будет работать нормально. Возвращает столбец с именами пользователей ( image ). Однако, если я уйду в ocp.membersin, я получу эту ошибку:

#1054 - Unknown column 'ocp.membersin' in 'on clause'

Это первый раз, когда я даже использовал IN в левом соединении, поэтому я немного растерялся.

Любая помощь была бы великолепна:)

Ответы [ 6 ]

2 голосов
/ 20 февраля 2009

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

2 голосов
/ 20 февраля 2009

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

0 голосов
/ 20 февраля 2009

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

0 голосов
/ 20 февраля 2009

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

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

Но если вам все еще нужно жить с этим, вы можете попробовать 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
0 голосов
/ 20 февраля 2009

Причина, по которой вы не можете заставить его работать, состоит в том, что сначала вам нужно нормализовать базу данных. Вы никогда не должны иметь НИКАКОГО списка идентификаторов в одном столбце.

...