Reputation: 6731
I have four tables one is a master table that contains columns for EmployeeID, VendorID and DriverID
Then I have corresponding tables for each of these: employees, vendors and drivers and they all have similar columns like first name, last name, etc.
So, I want to be able to pull all records from my master table and have the corresponding first name and last based on whether the master record is an employee, vendor or driver.
A row in the master table would like this for an employee
EmployeeID = 352
VendorID = 0
DriverID=0
Vendor would look like
EmployeeID = 0
VendorID = 954
DriverID=0
etc.
Help?
Upvotes: 2
Views: 151
Reputation: 2115
I dont the reason why this design was required. But this should work even if a single row has both EmplyeeID and VendorID as not 0
SELECT 'employee' AS src, EmployeeID AS ID, FirstName, LastName
FROM mastertable
JOIN employee
ON mastertable.EmployeeID = employee.ID
where mastertable.EmployeeID != 0
UNION
SELECT 'vendor' AS src, VendorID AS ID, FirstName, LastName
FROM mastertable
JOIN vendor
ON mastertable.VendorID = vendor.ID
where mastertable.VendorID != 0
UNION
SELECT 'driver' AS src, DriverID AS ID, FirstName, LastName
FROM mastertable
JOIN driver
ON mastertable.DriverID = driver.ID
where mastertable.DriverID != 0
Upvotes: 0
Reputation: 837946
You could use UNION ALL:
SELECT 'employee' AS src, EmployeeID AS ID, FirstName, LastName
FROM mastertable
JOIN employee
ON mastertable.EmployeeID = employee.ID
UNION ALL
SELECT 'vendor' AS src, VendorID AS ID, FirstName, LastName
FROM mastertable
JOIN vendor
ON mastertable.VendorID = vendor.ID
UNION ALL
SELECT 'driver' AS src, DriverID AS ID, FirstName, LastName
FROM mastertable
JOIN driver
ON mastertable.DriverID = driver.ID
This will work even if someone has more than one ID set (in this case they will get one row for each ID that is set).
You might also want to consider if it would be worth changing your schema to make it easier to query. Could you move all the common columns into the master table? Then you would only need to write the following query to get what you want:
SELECT ID, Type, FirstName, LastName, ...
FROM mastertable
Upvotes: 4
Reputation: 2212
This works:
SELECT (case when m.CustId > 0 then c.FirstName else case when m.EmpId > 0 then emp.FirstName end end) as FirstName, * FROM MAster m Left Join Employee emp ON m.EmpId = emp.EmpId Left Join Customer c ON m.CustId = c.CustIdster table to a Union of all the detail tables
Upvotes: 0
Reputation: 5347
Jim,
This can be accomplished via unions and left joins onto the master table, but I would like to suggest that you may want to look at the design. It seems that vendors, employees and drivers are all people - with things like first names, last names, addresses, phone numbers...etc. It seems that a "person" table would be appropriate to hold all this information, with additional tables that store information specific to their individual roles.
Your master table can then have a field for personID to join in generic people information, and another field(s) for an ID that can tie into role specific data.
Let me know if you'd like some clarity on this. With more information regarding your design needs, we can dig deeper.
Upvotes: 2
Reputation: 6297
This assumes that the other two id fields are null for a particular type:
SELECT NT.FirstName, NT.LastName FROM People P JOIN MasterTable MT ON P.Id = MT.EmployeeID
JOIN Drivers NT ON NT.Id = MT.DriverID WHERE DriverID IS NOT NULL
UNION
SELECT NT.FirstName, NT.LastName FROM People P JOIN MasterTable MT ON P.Id = MT.EmployeeID
JOIN Vendors NT ON NT.Id = MT.VendorID WHERE VendorId IS NOT NULL
UNION
SELECT NT.FirstName, NT.LastName FROM People P JOIN MasterTable MT ON P.Id = MT.EmployeeID
JOIN Employees NT ON NT.Id = MT.DriverID WHERE EmployeeID IS NOT NULL
You could also redesign your master type to have a PersonType field, and store a single id, avoiding the sparse data inherent in this design.
Upvotes: 0
Reputation: 4827
You probably want COALESCE, and methinks those zero id's maybe should be null, but anyway:
select master.id
, coalesce(emp.first_name,vend.first_name,drv.first_name)
as first_name
, -- repeat for other columns
from master
left
join employee emp on master.employeeId = emp.employeeId
left
join vendor vend on master.vendorId = vend.vendorId
left
join driver drv on master.DriverId = drv.driverId
This assumes that a person will be in only one of the three.
On a second branch of thought, if a person can only be in one of the three, this looks like a supsicious table design, perhaps there should only be one child table, but that would depend on what else is going on.
Upvotes: 3
Reputation: 43974
You could to do this using Left Joins and case statements but it would be horrible to maintain.
I would suggest that you write select queries for employees, vendors and drivers and then use a Union to concatenate the results and wrap the whole thing in to a view.
Upvotes: 0