2009-02-20 6 views
0

Cette petite erreur SQL me perturbe. (?) Il ne semble pas être un problème avec la requête, juste la portée, des exemples qui fonctionnent le mieux:Problème SQL, LEFT JOIN [..] IN()

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 une colonne (gangs_ocs_process.membersin) qui a une liste d'ID qui se sont joints (c.-à- 1,2,5). J'essaie d'obtenir les noms d'utilisateur pour chacun de ces ID (à partir de la table users) en une seule fois.

Le problème est LEFT JOIN users u ON u.userid IN (ocp.membersin)

Si je Substitue 1,2,4 dans pour ocp.membersin (mettre la liste littérale au lieu du nom de la colonne), il fonctionne bien. Il renvoie une colonne qui contient les noms d'utilisateur (image). Cependant, si je laisse dans le ocp.membersin, je reçois cette erreur:

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

C'est la première fois que je l'ai même utilisé dans des gauche rejoint donc je suis un peu perdu.

Toute aide serait génial :)

+0

désolé pour le 1 million de modifications. Pouvez-vous élaborer la relation entre gangs_ocs_process, gangs_oc, et les utilisateurs. – cmsjr

+0

C'est bon. La relation n'a pas beaucoup d'importance car elle renvoie la colonne sous forme de chaîne, ce qui ne fonctionnera pas correctement avec l'IN qui n'a besoin que d'une liste de valeurs. La plupart des modifications que vous avez effectuées ont fonctionné, mais nous avons tous les deux semblé manquer ce point jusqu'à ce que Jeremy l'indique – damnitshot

Répondre

2

Je ne pense pas que "IN" fonctionnera pour cette syntaxe. MySQL s'attend à ce que IN soit quelque chose qui s'apparente à un ensemble de données, pas une chaîne délimitée. Je pense que vous devez trouver un moyen de prendre des membres, de l'étendre dans un ensemble de données avec lequel MySQL peut travailler (peut-être une table temporaire), et de vous joindre à cela.

+0

Oui - Je suis assez sûr que c'est maintenant. La colonne a 1,2,3, mais le transforme en 'userid IN ('1,2,3')', qui n'en récupère qu'une seule. Je vais devoir développer/utiliser deux requêtes – damnitshot

0

La raison pour laquelle vous ne pouvez pas le faire fonctionner est parce que vous devez d'abord obtenir votre base de données NORMALISÉE. Vous ne devriez JAMAIS, JAMAIS avoir une liste d'ID dans une seule colonne.

+0

J'utilise (j'essaie) IN parce que les membres dans col ont plusieurs valeurs, et je reçois plusieurs lignes à partir du table users (en les regroupant avec GROUP_CONCAT()). J'ai aussi essayé votre méthode, mais elle indique toujours une colonne inconnue. – damnitshot

+0

Ok, votre problème est simple: votre base de données est DENORMALISÉE et c'est la source de vos problèmes. –

0

Ceci est un mauvais chemin pour garder l'adhésion.

Mais si vous avez encore besoin de vivre avec elle, vous pouvez essayer REGEXP correspondant à tester l'adhésion:

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

Il semble fonctionner en partie, je l'ai déplacé vers deux jointures comme vous l'avez posté.L'erreur ne se produit pas, même si la colonne 'membersin' est '1,2,3', elle ne renvoie qu'une seule ligne' users' (j'ai utilisé la même syntaxe IN() que ci-dessus) – damnitshot

+0

Voir la mise à jour . – Quassnoi

0

Après avoir pris un autre regard, je pense que votre problème est d'essayer d'agréger au mauvais endroit aussi bien comme la syntaxe IN et que vous devez agréger dans une sous-requête restreinte par le contenu de l'IN. Je ne connais pas assez votre schéma pour le rendre correct, mais vous voulez quelque chose comme ça. SomeKeyfield devrait rapporter à 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

Etes-vous sûr 'membersin' est dans la table 'gangs_ocs_process', et non la table 'gangs_ocs'?

+0

J'ai fait un double contrôle heh, mais oui c'est le cas. – damnitshot

2

Si vous avez des chaînes délimitées dans votre table, vous avez un problème de conception dans votre base de données. Ajouter une nouvelle table pour contenir ces valeurs.