Исследование в JOINs с отношениями многие ко многим - PullRequest
2 голосов
/ 04 июля 2010

Рассмотрим, если хотите, следующие таблицы:

Модель для отпуска http://imagetiger.org/images/vacatilrl.png

Это может показаться странной структурой, но позвольте мне объяснить. Целью этой структуры является создание отчета со списком всех людей, за исключением тех, кто находится в отпуске (для простоты мы будем делать вид, что запись об отпуске будет существовать только в том случае, если человек находится в отпуске.)

Причина, по которой у меня вообще есть таблица Vacation, заключается в том, что таблица Event - это таблица более общего использования для «незначительных» событий, в то время как таблица Vacation включает в себя больше деталей, таких как местоположение и дата.

Похоже, я не могу понять, как разработать запрос, который включает, скажем, Person.personId и Vacation.location, но только те PersonId, которые существуют в Person_Vacation. Или наоборот, только PersonIds, которые НЕ существуют в Person_Vacation.

Кроме того, кажется ли это наилучшим способом реализации этого решения с точки зрения дизайна? Любые идеи о том, что я мог сделать неправильно или предлагали улучшения?

РЕДАКТИРОВАТЬ: Может быть, я просто не слишком хорош в сообщении своих намерений: получается, что просто взять людей в отпуск легко, но я хотел бы выполнить обратное, в основном все люди НЕ в отпуске .

Ответы [ 2 ]

5 голосов
/ 04 июля 2010

В плане дизайна я не понимаю, зачем вам нужно Person_Vacation.Если я правильно понимаю ваш дизайн, каждый отпуск - это событие (то есть «наследование»), поэтому связь между Vacation и Person может быть установлена ​​через Person_Event.Тогда запросы будут:

Количество человек в отпуске:

SELECT P.PersonID, V.locaton
FROM Person P, Vacation V, Person_Event PE
WHERE P.personid = PE.personID AND PE.eventid = V.eventid

Число лиц, не участвующих в отпуске:

SELECT P.PersonID, E.title
FROM Person P, Person_Event PE, Event E
WHERE P.personid = PE.personID AND PE.eventid = E.eventid
AND E.eventID NOT IN (SELECT eventid FROM Vacation)

Число лиц, не входящих в любой каникулы:

SELECT P.PersonID, E.title
FROM Person P, Person_Event PE, Event E
WHERE P.personid = PE.personID AND PE.eventid = E.eventid
AND P.personID NOT IN 
  (SELECT personid FROM Person_Event PE, Vacation V WHERE PE.eventid = V.eventid)

Если вы хотите использовать свой собственный дизайн, вам нужно решить, будете ли вы включать отпуск человека только в Person_Vacation или в Person_Vacation и Person_Event.Если вы сделаете первое, то приведенные выше запросы станут немного проще.

Однако я все равно проголосовал бы за мой дизайн, потому что то, что вы по сути делаете, - это преждевременное разделение данных, чтобы получить немного производительности / простоты.Это может не окупиться в долгосрочной перспективе.

0 голосов
/ 04 июля 2010

Вероятно, я не до конца понял ваш дизайн базы данных.Если Vocation также является событием и в таблице Person_Event есть все события, которые касались человека personId, то таблица должна содержать подмножество Person_Vacation, и его можно исключить.Более того, у всех людей иногда есть призвание, поэтому я считаю более логичным включать даты в некоторые таблицы.

Тем не менее, как я понимаю ваш дизайн базы данных, вы можете получить результаты, которые вы хотите получить с помощью запроса, подобного следующему

SELECT p.name, e.title
FROM Person AS p
    INNER JOIN Person_Event AS pe ON p.personId = pe.personId
    INNER JOIN [Event] AS e ON pe.eventId = e.eventId
    LEFT OUTER JOIN Vacation AS v ON e.eventId = v.eventId
WHERE v.eventId IS NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...