简体   繁体   中英

What kind of JOIN or WHERE clause do I need?

I've been trying to contrust a query to grab columns for 3 tables, but I keep getting mismatched rows.

These are my tables:

Messages
- messageID
- sender (can either be a customerID or employeeID) - receiver (can either be a customerID or employeeID)

(Note: for each message it will contain only 1 customer and 1 employee, ie. Customer's dont interact with eachother and employees don't message eachother also)

Customer
- customerID

Employee
- employeeID
- departmentID

DEPARTMENT
- departentID
- departmentName

For a particular customer with customerID = 5, I want to figure out what is the DepartmentName of the employee they were talking to.

My Intial attemp at this was:

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;

However this returns way more rows than expected. I think it's because sender or receiver can potentially be the employeeID.

My 2nd guess is maybe i have to join tables, but i dont have much experience in this. If anyone could show me or tell me how to perform this query I would appreciate it.

The fundamental problem is that you are missing parentheses around this clause:

sender = '5' OR receiver = '5' 

However, I would recommend that you use ANSI-style joins to make the query more readable too.

This should help:

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');

Did you try this:

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'

Your problem is actually that you can have an Employee with the same id as a Customer , with no way to tell the two apart.

I think that a better way to do this is to treat both Customers and Employees as Users , and to link the User table to a Role table that tells you whether they are a customer or an employee.

An alternative way is to have a Message table that has one field for EmployeeID and one field for CustomerID, and one field to specify whether this is customer to employee, or employee to customer. In other words, a message that was sent, or a message that was received.

Finally, if you are sure that there can be no clashes with Customer and Employee IDs, then this will probably do for your query:

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;

The above specifies that the receiver and sender can't both be employees or customers.

UPDATE: To clarify, a single field should not refer to two other tables, because that makes it impossible to specify it as a foreign key. There may be clashes in the identity columns of the two tables. For example, what happens if you have a Customer with ID 5, and an Employee with ID 5?

There are techniques for dealing with this situation, some of which are shown here: Foreign Key to multiple tables

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM