2013-11-25 2 views
0

Я пытался удержать запрос, чтобы захватить столбцы для 3 таблиц, но я продолжаю получать несоответствующие строки.Какое предложение JOIN или WHERE мне нужно?

Это мои таблицы:

Сообщения
- MESSAGEID
- отправитель (может быть либо CUSTOMERID или EmployeeID) - приемник (может быть либо CUSTOMERID или EmployeeID)

(Примечание : для каждого сообщения он будет содержать только 1 клиента и 1 сотрудника, т. е. клиент не взаимодействует с пользователем, а сотрудники также не сообщают друг другу)

Заказчик
- CUSTOMERID

Сотрудник
- EmployeeID
- DepartmentID

ОТДЕЛ
- departentID
- departmentName

Для конкретного клиента с CUSTOMERID = 5, я хочу, чтобы выяснить, что такое DepartmentName сотрудника, с которым они разговаривали.

Мои Intial attemp на это:

SELECT * FROM Messages,Employee, Departmnet, 
WHERE sender = '5' OR receiver = '5' 
AND (Employee.employeeID = Messages.sender OR Employee.employeeID = Messages.Receiver) 
AND Employee.departmentID = Department.DepartmentID; 

Однако это возвращает путь больше строк, чем ожидалось. Я думаю, что это связано с тем, что отправитель или получатель потенциально может быть идентификатором employeeID.

Мое второе предположение, возможно, мне нужно присоединиться к столам, но у меня нет большого опыта в этом. Если бы кто-нибудь мог показать мне или сказать мне, как выполнить этот запрос, я был бы признателен.

+0

сообщения некоторых выборочные данные и желаемый результат. – Mihai

+1

customerId и employeeId - это только идентификаторы auto increment, или вы удостоверились, что клиент и сотрудник не могут иметь одинаковый идентификатор? – rakeshjain

+0

@rakeshjain они не являются значениями автоматического увеличения, а способ создания Сообщений гарантирует, что Клиент будет только сообщать сотруднику, а сотрудник будет отправлять сообщение только клиенту. –

ответ

1

ли вы попробовать это:

SELECT * FROM Messages m 
INNER JOIN Employee e 
INNER JOIN Departmnet d 
ON ((m.sender=e.employeeId || m.receiver=e.employeeId) d.departmentId=e.departmentId) 
WHERE m.sender = '5' OR m.receiver = '5' 
+0

Я протестировал этот запрос, и это решение. Просто нужны parens вокруг предложения where .ie WHERE (m.sender = '5' ИЛИ ​​m.receiver = '5') –

+0

@ user3032422 если он работает, можете ли вы принять/опросить ответ? – rakeshjain

+0

У меня нет 15 очков репутации, чтобы сделать это, но как только я получу их, я обещаю вернуться сюда и сделать это. –

2

Основная проблема заключается в том, что вам не хватает скобки вокруг этого пункта:

sender = '5' OR receiver = '5' 

Однако я бы рекомендовал использовать ANSI-стиль присоединяется сделать запрос более удобным для чтения тоже.

Это должно помочь:

SELECT * 
FROM Messages 
INNER JOIN Employee ON (Employee.employeeID = Messages.sender OR Employee.employeeID = Messages.Receiver) 
INNER JOIN Department ON Employee.departmentID = Department.DepartmentID 
WHERE (Messages.sender = '5' OR Messages.receiver = '5'); 
+0

Спасибо .. это работает –

0

Ваша проблема на самом деле, что вы можете иметь Employee с тем же идентификатором, как Customer, не имея возможности сказать два друг от друга.

Я думаю, что лучший способ сделать это, чтобы рассматривать как Customers и Employees как Users и связать User таблицы в Role таблицу, которая говорит вам, являются ли они клиентом или сотрудником.

Альтернативный способ состоит в том, чтобы таблица сообщений имела одно поле для EmployeeID и одно поле для CustomerID и одно поле, чтобы указать, является ли это клиентом для сотрудника или сотрудника для клиента. Другими словами, отправленное сообщение или сообщение, которое было получено.

Наконец, если вы уверены, что не может быть никаких столкновений с Клиентом и идентификаторами Employee, то это, вероятно, сделать для вашего запроса:

SELECT * 
FROM Messages 
INNER JOIN Employee 
ON (
    (receiver = '5' AND Employee.employeeID = sender) OR 
    (sender = '5' AND Employee.employeeID = receiver) 
) 
INNER JOIN Department 
ON Employee.departmentID = Department.departmentID; 

выше указывает, что приемник и передатчик не может и быть сотрудниками или клиентами.

ОБНОВЛЕНИЕ: Чтобы уточнить, одно поле не должно ссылаться на две другие таблицы, поскольку это делает невозможным указание его как внешнего ключа. В столбцах идентификации двух таблиц могут быть столкновений. Например, что произойдет, если у вас есть клиент с идентификатором 5 и сотрудник с идентификатором 5?

Существует методы для решения этой ситуации, некоторые из которых приведены здесь: Foreign Key to multiple tables

+0

Не поощряйте использование SQL Antipatterns, как неявные объединения. Давайте попробуем взять людей в 21-й век. – HLGEM

+1

Переписан. В моей защите я хотел бы отметить, что ОП имеет большие проблемы, чем неявные vs явные объединения. Подобно дизайну базы данных, который исключает использование внешних ключей. –

+0

@GustavBertram имеет низкий удар .. однако я использую внешние ключи в моей схеме базы данных. Вместо того, чтобы использовать мою точную схему базы данных, я опускал свой пример, чтобы сделать его менее запутанным и более читаемым. –

Смежные вопросы