2009-02-24 3 views
1

J'ai 2 tables:Comment utiliser INNER JOIN dans le scénario?

'utilisateurs' Tableau

 
id  username 
---- -------- 
0001 user1   
0002 user2   
0003 user3   
0004 user4  

de la table 'Amis de

 
user_id friend_id friend 
------- --------- ------ 
0001  0004  1 
0002  0004  1 
0005  0004  0 

Comment afficher le nom de tous les amis user4? si dans la table des amis, la colonne ami, 1 indique qu'ils sont amis, 0 indiquent qu'ils ne sont toujours pas amis.

J'utilise INNER JOIN, qui ressemble à ceci:

SELECT users.username 
FROM `users` 
INNER JOIN `friends` ON users.id = friends.friend_id 
WHERE friends.user_id = 0004 
    AND friend = 1; 

Mais ce que je reçois est:

user4 et user4 au lieu de user1 et user2

peut me aider?

Répondre

0
SELECT u.username 
FROM Friends f, Users u 
WHERE f.friend = 1 AND 
((f.friend_id = @userid AND f.user_id = u.id) OR 
    (f.user_id = @userid AND f.friend_id = u.id)) 
1
select u.username 
from friends f, users u 
where f.friend_id='0004' and f.friend=1 and f.id=u.user_id; 

Edit: C'est le même que:

select u.username 
from friends f inner join users u on f.id=u.user_id 
where f.friend_id='0004' and f.friend=1; 
+0

Il n'y a pas de champ u.user_id. –

+0

merci de le signaler. le fixe (et d'autres choses) – tehvan

+0

J'ai essayé toutes les réponses. Il suffit de changer le u.user_id à u.id, son fonctionnement ... Mais les réponses chris mehrdad et gordon ne fonctionnent pas .. – roa3

3
SELECT users.username 
FROM `users` 
INNER JOIN `friends` ON users.id = friends.user_id 
WHERE friends.user_id = 0004 
    AND friend = 1; 
+0

J'ai essayé peu de fois, ne fonctionne pas .. – roa3

+0

je pense que le "WHERE" doit être "friends.friend_id = 0004" au lieu de user_id –

+0

Yup, après avoir changé de friends.user_id à friends.friend_id, son fonctionnement maintenant .. Merci un million – roa3

1

Êtes-vous sûr que vous ne voulez pas lier la table d'amis à la table des utilisateurs sur la user_id place de l'ami_id? Ensuite, changez la clause where pour utiliser le friend_id au lieu de user_id. Il existe différentes manières de formater la jointure, mais la façon dont vous le faites en utilisant une jointure interne semble correcte.

SELECT users.username 
FROM `users` 
INNER JOIN `friends` ON users.id = friends.user_id 
WHERE friends.friend_id = 0004 
AND friend =1 
4
SELECT u.username 
FROM Friends f, Users u 
WHERE f.user_id = u.id 
     AND f.friend = 1 
     AND f.friend_id = '0004' 
+0

pas besoin de spécifier l'ID utilisateur 0004 ?? – roa3

+0

Le @userID peut être utilisé comme une requête paramétrée, vous pouvez donc entrer le '0004' comme paramètre. J'ai modifié la sélection ci-dessus afin que vous puissiez l'exécuter directement. Cependant, vous devriez vraiment utiliser des requêtes paramétrées pour vous protéger contre les attaques par injection SQL. N'ajoutez jamais '0004' à votre requête. –

+0

Qu'est-ce que je veux dire est, qu'est-ce que quelqu'un est entré 'OU 1 = 1 - Vous obtiendrez avec et f.friend_id =' 'OR 1 = 1 - 0004' –

1

Voulez-vous dire comme ça?

SELECT u.username 
FROM friends AS f 
INNER JOIN users AS u USING user_id 
WHERE f.friend_id = 0004 AND f.friend = 1 
1
select U.Username 
from 
    Users as U 
    inner join Friends as F on U.Id = F.user_id and F.friend = 1 
where 
    F.friend_id = '0004' 

Si la table d'amis est juste une table de mappage vous voulez pas la carte dans les deux sens?

select U.Username 
from 
    Users as U 
    left outer join 
    (
     select 
      F.user_id as Id 
     from 
      Friends as F 
     where 
      F.friend_id = '0004' 
     and 
      F.friend = 1 

    ) as Mapping1 on Mapping1.Id = U.id 
    left outer join 
    (
     select 
      F.friend_id as Id 
     from 
      Friends as F 
     where 
      F.user_id = '0004' 
     and 
      F.friend = 1 

    ) as Mapping2 on Mapping2.Id = U.id 

where 
    Mapping1.Id is not null or Mapping2.Id is not null 
+0

C'est trop avancé pour moi. Btw, votre méthode serait-elle plus rapide (plus rapide dans la récupération des données) que les autres? – roa3

+0

Je suppose que vous faites référence à la deuxième requête. C'est une question de complétude si vous voulez la recherche bidirectionnelle alors c'est jusqu'ici la seule requête qui fait le travail. En ce qui concerne la vitesse qui dépendra de vos index de champ de table. –

0

dmcgiv a un point important que vous devez penser à si le mappage d'ami est bi-directionnel (à savoir, si A est amis avec B alors B est automatiquement amis avec A). Vous devez vérifier si l'utilisateur qui vous intéresse est situé de chaque côté du mappage de table des amis.

Vous pouvez soit le faire de façon dmcgiv, ou d'une autre manière serait d'insérer simplement des liens dans les deux sens dans la table des amis lorsque vous ajoutez une amitié. Par exemple, si l'utilisateur est 0004 amis avec l'utilisateur 0006, vous insérez dans la table Amis:

user_id | friend_id | friend 
0004 | 0006  | 1 
0006 | 0004  | 1 

Je ne pense pas que vous avez vraiment besoin d'une colonne ami, par la voie. À moins qu'il y ait une raison de suivre les «non-amis», vous pouvez simplement supprimer le mappage de la table des amis si l'amitié se termine.

0

nom d'utilisateur, sélectionnez des utilisateurs nous où us.id dans ( sélectionnez f. [User_id] des utilisateurs u jointure interne amis f ON u.id = f.friend_id où f.ami = 1)

0

Essayez cette requête

select u.username from users u join friends f on u.id=f.user_id and f.friend=1;