как объединить 2 или более таблиц мостов в один запрос

у меня есть следующие таблицы:

Таблица: Люди (id, имя, фамилия, возраст, телефон и т. Д.)
Таблица: Роли (id, имя)
Таблица: Навыки (id, имя)
Таблица: People_Roles (id, personID ^, roleID ^)
Таблица: People_Skills (id, personID ^, skillID ^)

^ = foreign key

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

Person.First, Person.Last, Roles.Name, Skills.Name


person leora    schedule 19.12.2009    source источник
comment
Это похоже на домашнее задание   -  person monksy    schedule 19.12.2009
comment
к сожалению нет . . прямо сейчас я выполняю много запросов (по одному на строку), и это занимает много времени, поэтому я пытаюсь объединить все свои запросы в один запрос. .   -  person leora    schedule 19.12.2009
comment
@monksy Какая разница, если это домашнее задание? Вопрос есть вопрос!   -  person Twifty    schedule 17.06.2014


Ответы (2)


SELECT p.first, p.last, r.name, s.name
FROM People p
LEFT JOIN People_Roles pr
ON pr.personID = p.id
INNER JOIN Roles r
ON pr.roleID = r.id
LEFT JOIN People_Skills ps
ON ps.personID = p.id
INNER JOIN Skills s
ON ps.skillID = s.id

Этот запрос выберет вам всех людей, даже тех, кому не назначено Roles или Skills.

person Li0liQ    schedule 19.12.2009
comment
но если я делаю все внутренние соединения, если есть человек с навыком, а не ролью, тогда он не будет показывать записи. Я хочу увидеть все комбинации. я думал, что это внешнее соединение ?? - person leora; 19.12.2009
comment
@oo Я написал об этом комментарий :). Обновил ответ для вашего удовольствия. - person Li0liQ; 19.12.2009
comment
это по-прежнему дает мне строки только там, где есть навык или роль. . Что, если есть человек без навыков или рядов? . как это проявится? - person leora; 19.12.2009
comment
@oo этот человек будет отображаться как человек с NULL в именах навыков и ролей. Как только мы используем LEFT JOIN, он возвращает ВСЕ записи из левой таблицы, что означает таблицу People. - person Li0liQ; 19.12.2009

Этот запрос будет работать:

SELECT Person.First, Person.Last, Roles.Name, Skills.Name  
FROM People 
    LEFT JOIN People_Skills 
        ON People.id = People_Skills.personID
    INNER JOIN Skills
        ON People_Skills.skillID = Skills.id
    LEFT JOIN People_Roles 
        ON People.id = People_Roles.personID
    INNER JOIN Roles
        ON People_Roles.roleID = Skills.id

Кстати, почему у ваших "мостовых" таблиц свой ID. Я бы просто использовал составной ключ, состоящий из PersonID и соответствующего внешнего ключа (skillsID или roleID) чтобы каждая пара могла быть изготовлена ​​только один раз.

person Oded    schedule 19.12.2009
comment
но если я делаю все внутренние соединения, если есть человек с навыком, а не ролью, тогда он не будет показывать записи. Я хочу увидеть все комбинации. я думал, что это внешнее соединение ?? - person leora; 19.12.2009
comment
согласился, но я думаю, мне нужно будет разобраться с этим в коде. . или вернуться к моему первоначальному методу создания отдельного запроса для каждой таблицы мостов для каждой записи в таблице людей. . - person leora; 19.12.2009
comment
Сделайте предложение where и compare is Null, чтобы удалить ненужные пустые строки. - person Vaccano; 19.12.2009
comment
И левые соединения, вероятно, были бы лучше, чем полные соединения - person Vaccano; 19.12.2009
comment
Обновлен запрос, чтобы вернуть полный набор результатов, как описано. - person Oded; 19.12.2009
comment
Я пытаюсь понять, стоит ли оно того, так как у меня есть около 10 различных таблиц мостов. . кодирование его в цикле определенно намного проще, но не уверен в производительности. . - person leora; 19.12.2009
comment
С точки зрения производительности, 10-кратный вызов БД будет стоить намного дороже, чем ее однократный вызов и получение большего набора результатов, если только набор результатов не будет огромным ... - person Oded; 19.12.2009
comment
а также сложность синтаксического анализа результатов и их перенормировки в моей объектной модели, поскольку моя объектная модель представляет собой объект Person с массивом Skills и массивом Roles. - person leora; 19.12.2009
comment
Всегда есть компромисс ... вам нужно решить, какую часть из них вы готовы принять. - person Oded; 19.12.2009