2009-09-12 11 views
5

J'ai une table de projets qui a deux clés étrangères pour les utilisateurs (user_id et winner_user_id), une pour le propriétaire du projet et une pour le gagnant du projet. Quelque chose commeSQL, Comment faire une requête avec plusieurs clés étrangères dans une table?

+----------------+-------------------------+------+-----+---------+----------------+ 
| Field   | Type     | Null | Key | Default | Extra   | 
+----------------+-------------------------+------+-----+---------+----------------+ 
| project_id  | int(10) unsigned  | NO | PRI | NULL | auto_increment | 
| start_time  | datetime    | NO |  | NULL |    | 
| end_time  | datetime    | NO |  | NULL |    | 
| title   | varchar(60)    | NO |  | NULL |    | 
| description | varchar(1000)   | NO |  | NULL |    | 
| user_id  | int(11)     | NO |  | NULL |    | 
| winner_user_id | int(10) unsigned  | YES |  | NULL |    | 
| type   | enum('fixed','auction') | YES |  | NULL |    | 
| budget   | decimal(10,0)   | YES |  | NULL |    | 
+----------------+-------------------------+------+-----+---------+----------------+ 

Maintenant, je suis en train en une seule requête pour obtenir des informations sur les projets et les données sur les deux utilisateurs.

Je formulé une requête comme

SELECT projects.project_id, projects.title, projects.start_time, 
      projects.description, projects.user_id, projects.winner_user_id, 
      users.username as owner, users.username as winner 
     FROM projects,users 
     WHERE projects.user_id=users.user_id 
     AND projects.winner_user_id=users.user_id 

qui retourne un ensemble vide de toute évidence. Le vrai problème est de savoir comment référencer ces différents user_ids. J'ai même essayé d'utiliser le mot-clé AS et ensuite en utilisant le nom que j'avais créé dans la même requête sql mais apparemment cela ne fonctionne pas.

Pour rendre les choses claires à la fin, je voudrais quelque chose comme

+------------+-------------------------------------------------+---------------------+---------+----------------+--------------+--------------+ 
| project_id | title           | start_time   | user_id | winner_user_id | owner  | winner  | 
+------------+-------------------------------------------------+---------------------+---------+----------------+--------------+--------------+ 
|   1 | CSS HTML Tableless expert for site redesign  | 2009-09-01 21:07:26 |  1 |    3 | mr X  | mr Y  | 
|   2 | High Quality Ecommerce 3-Page Design HTML & CSS | 2009-09-01 21:10:04 |  1 |    0 | mr X  | mr Z  | 

Comment puis-je construire une requête pour gérer cette situation?

Merci d'avance.

Répondre

8

Vous êtes proche, mais vous devez rejoindre la table des utilisateurs deux fois, une fois sur le propriétaire et une fois sur le gagnant. Utilisez un alias de table pour différencier les deux.

SELECT 
     projects.project_id 
    , projects.title 
    , projects.start_time 
    , projects.description 
    , projects.user_id 
    , projects.winner_user_id 
    , users.username as owner 
    , winnerUser.username as winner 
FROM projects 
INNER 
    JOIN users 
    ON projects.user_id=users.user_id 
INNER 
    JOIN users winnerUser 
    ON projects.winner_user_id=winnerUser.user_id 
+0

Merci beaucoup! Je n'utilise jamais vraiment la syntaxe INNER JOIN mais je trouve intéressant que winnerUser ne soit pas spécifié directement après FROM. – zenna

2
SELECT ... FROM users AS winers, users AS owners 
WHERE projects.user_id=owners.user_id 
     AND projects.winner_user_id=winners.user_id 
1

Qu'en est-il d'utiliser quelque chose comme ceci:

SELECT projects.project_id, projects.title, projects.start_time, 
    projects.description, projects.user_id, projects.winner_user_id, 
    user_owner.username as owner, user_winner.username as winner 
FROM projects 
    inner join users user_owner on user_owner.user_id = projects.user_id 
    inner join users user_winner on user_winner.user_id = projects.winner_user_id 

Vous devez d'abord le projet, puis intérieur vous rejoindre sur le propriétaire (en utilisant un alias spécifique), puis jointure sur le gagnant (en utilisant un autre alias spécifique). Et, dans la clause select, vous utilisez ces alias pour obtenir l'information que vous voulez - même si vous avez besoin de restreindre quoi que ce soit dans une clause where, btw.

Remarque: Si vous voulez également des projets qui n'ont pas encore de gagnant, vous pouvez utiliser une jointure gauche au lieu d'une interne.

0
SELECT u1.user_id AS user_id, u2.user_id AS AS winner_id 
FROM projects p 
    INNER JOIN users u1 ON p.user_id=u1.user_id 
    INNER JOIN users u2 ON p.winner_user_id=u2.user_id 
0

Cela devrait fonctionner, et revenir NULL si le gagnant dans inconnu (quand winner_user_id est null)

SELECT projects.project_id, 
    projects.title, 
    projects.start_time, 
    projects.description, 
    projects.user_id, 
    projects.winner_user_id, 
users_owner.username as owner, 
users_winner.username as winner 
FROM projects 
    INNER JOIN users AS users_owner ON users_owner.user_id = projects.user_id 
    LEFT OUTER JOIN users AS users_winner ON users_winner.user_id = projects.winner_user_id 
Questions connexes