2011-03-06 6 views
0

J'ai 2 tables; les membres et les équipesPourquoi cette requête MySQL complexe ne fonctionne-t-elle pas?

Table membres

MemberID, prenom, lastName

(prenom et nomFamille sont des index en texte intégral)

équipes Table team_id, member1ID, member2ID

Voici ma requête

$sql = "SELECT a.* ";  
$sql .= "FROM teams a WHERE "; 
$sql .= "a.member1ID IN (SELECT b.memberID FROM members b "; 
$sql .= "WHERE MATCH(b.firstName, b.lastName) AGAINST('$q' IN BOOLEAN MODE)) "; 
$sql .= "OR a.member2ID IN (SELECT b.memberID FROM members b "; 
$sql .= "WHERE MATCH(b.firstName, b.lastName) AGAINST('$q' IN BOOLEAN MODE)) "; 

if($year) 
    $sql .= "AND a.team_y = $year "; 

$sql .= "ORDER BY a.team_num ASC "; 

if($limit)  
    $sql .= "$limit"; 

Cette requête doit être proche, mais elle ne fonctionne pas encore. J'essaie de créer une requête qui me permettra de voir toutes les équipes sur lesquelles "$ q" est activé.

Ex. $ q = doe, Montre-moi toutes les équipes qui sont actives.

Cette requête doit sortir les équipes.

+0

Veuillez reformuler le titre de votre question car "J'ai besoin d'aide" n'est pas une question. –

+1

Il est difficile de saisir la requête. Montrez-nous la requête complète - echo $ sql; –

+0

normalement il y aurait 3 tables: équipes, membres, membres d'équipe. mais puisque vous utilisez 2 table, je vous suggère de changer la façon dont vous interrogez. D'ailleurs tu as oublié le mot LIMIT avant $ limit – frail

Répondre

2

Une raison possible votre requête ne fonctionne pas est il y a une longueur minimale sur le plein recherche de texte, par défaut à 4 caractères. "doe" échouerait ce match. Vous pouvez augmenter cette via variable « ft_min_word_len »
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_ft_min_word_len

Par ailleurs, si vous voulez éviter normalisant (ce qui est toujours le « meilleur » chemin à parcourir), vous pouvez utiliser au moins rejoignons au lieu de sous -selects .. eg (les noms des champs sont renommés pour enregistrer en tapant)

select t.* from teams t 
inner join members me1 on t.m1 = me1.id 
inner join members me2 on t.m2 = me2.id 
where MATCH(me1.fname, me1.lname, me2.fname, me2.lname) 
    AGAINST('smith' IN BOOLEAN MODE); 
+0

Excellente solution! Je ne pensais pas à l'intérieur de rejoindre la même table sur différentes colonnes et alias. Cela a fonctionné un régal! – rprincejr

2

Normalize your database.

Dans votre cas, cela signifierait avoir une table Team (team_id, nom, quelle que soit d'autre), une table Member (member_id, prenom, last_name), et une table MemberToTeam (member_id, team_id). En d'autres termes, déplacez les member1ID et member2ID dans leur propre table. Suite à cette pratique, outre le fait d'améliorer votre schéma de base de données au sens général, la requête qui vous dérange devient triviale à écrire.

Si vous connaissez le member_id:

SELECT team_id FROM MemberToTeam WHERE member_id = 1 

Si vous effectuez une recherche par nom ou prénom:

SELECT mtt.team_id FROM Member m 
LEFT JOIN MemberToTeam mtt ON m.member_id = mtt.member_id 
WHERE m.first_name LIKE '%your search string here%' OR m.lastname LIKE '%your search string here%' 
+0

Je ne suis pas toujours en faveur de la normalisation, mais s'il y a une base de données qui peut bénéficier d'une normalisation c'est bien ça :) – extraneon

+0

ok, donc si je me fais l'idée d'ajouter un La 3ème table nommée memberToTeam, j'ai quelques questions. Que se passe-t-il lorsqu'une équipe est éditée et que l'un des membres de l'équipe change? Je ne sais pas vraiment comment l'enregistrement memberToTeam existant peut être mis à jour parce que le memberID a changé dans l'enregistrement d'équipe. – rprincejr

+0

@rprincejr: Si je vous comprends bien, vous supposez que la table d'équipe aurait toujours member1ID & member2ID. Exemple de Jon (3 tables), ce n'est pas nécessaire. Normaliser (déplacer les champs member1ID et member2ID vers une nouvelle table, dépend vraiment de ce que vous essayez d'accomplir (c'est-à-dire que votre équipe a TOUJOURS 2 membres SEULEMENT) Dans ce cas, peut-être que la structure de votre table est bonne. Voir ma réponse pour plus d'informations –