2009-09-12 26 views
5

Tengo una tabla de proyectos que tiene dos claves foráneas para usuarios (user_id y winner_user_id), una para el propietario del proyecto y otra para el ganador del proyecto. Algo comoSQL, ¿Cómo consultar con múltiples claves foráneas en una tabla?

+----------------+-------------------------+------+-----+---------+----------------+ 
| 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 |    | 
+----------------+-------------------------+------+-----+---------+----------------+ 

Ahora estoy intentando en una sola consulta obtener información sobre los proyectos y los datos sobre ambos usuarios.

Así que formula una consulta como

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 

que devuelve un conjunto vacío, obviamente. El verdadero problema es cómo hago referencia a estos diferentes user_ids. Incluso intenté usar la palabra clave AS y luego usar el nombre que había creado en la misma consulta sql pero aparentemente eso no funciona.

Para hacer las cosas claras al final me gustaría algo así como

+------------+-------------------------------------------------+---------------------+---------+----------------+--------------+--------------+ 
| 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  | 

¿Cómo puedo construir una consulta de manejar esto?

Gracias de antemano.

Respuesta

8

Estás cerca, pero debes unirte a la tabla de usuarios dos veces, una vez al propietario y otra al ganador. Use un alias de tabla para diferenciar los dos.

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

Gracias mucho! Nunca uso realmente la sintaxis INNER JOIN, pero me parece interesante que winnerUser no se especifique directamente después de 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é pasa con el uso de algo como esto:

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 

primer lugar, tiene el proyecto, a continuación, se inscribe interior del propietario (usando un alias específico) y unirse a continuación interno en el ganador (usando otro alias específico).

Y, en la cláusula de selección, utiliza esos alias para obtener la información que desea, lo mismo si necesita restringir algo en una cláusula where, por cierto.

Nota: si también desea proyectos que aún no tienen un ganador, es posible que desee utilizar una combinación izquierda en vez de una interna.

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

Esto debería funcionar, y devolver NULL si el ganador en desconocido (cuando winner_user_id es nulo)

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 
Cuestiones relacionadas