SQL, Как сделать запрос с несколькими внешними ключами в таблице? - PullRequest
5 голосов
/ 12 сентября 2009

У меня есть таблица проектов, в которой есть два внешних ключа для пользователей (user_id и winner_user_id), один для владельца проекта и один для победителя проекта. Что-то вроде

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

Теперь я пытаюсь одним запросом получить информацию о проектах и ​​данные об обоих пользователях.

Итак, я сформулировал запрос как

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

Который, очевидно, возвращает пустой набор. Реальная проблема заключается в том, как я могу ссылаться на эти разные user_ids. Я даже пытался использовать ключевое слово AS и затем использовать имя, которое я создал в том же SQL-запросе, но, видимо, это не работает.

Чтобы прояснить ситуацию в конце я хотел бы что-то вроде

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

Как я могу построить запрос для обработки этого?

Заранее спасибо.

Ответы [ 5 ]

8 голосов
/ 12 сентября 2009

Вы близки, но вам нужно присоединиться к пользовательской таблице дважды, один раз за владельца и один раз за победителя. Используйте псевдоним таблицы, чтобы различать их.

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
2 голосов
/ 12 сентября 2009
SELECT ... FROM users AS winers, users AS owners 
WHERE projects.user_id=owners.user_id
        AND projects.winner_user_id=winners.user_id
1 голос
/ 12 сентября 2009

Как насчет использования что-то вроде этого:

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

Сначала у вас есть проект, затем вы присоединяетесь к внутреннему владельцу (используя один конкретный псевдоним) , а затем внутреннее присоединение к победителю (используя другой конкретный псевдоним) .

И в предложении select вы используете эти псевдонимы для получения необходимой информации - то же самое, если вам нужно было что-то ограничить в предложении where, кстати.

Примечание: если вам также нужны проекты, у которых еще нет победителя, вы можете использовать левое соединение вместо внутреннего.

0 голосов
/ 12 сентября 2009

Это должно сработать, и вернуть NULL, если победитель неизвестен (когда winner_user_id равен нулю)

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
0 голосов
/ 12 сентября 2009
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...