SQL Server 2008 JOIN问题

时间:2011-01-21 17:25:11

标签: sql sql-server

我有四个表,一个是主表,包含EmployeeID,VendorID和DriverID的列

然后我为每个人提供相应的表格:员工,供应商和司机 它们都有类似的名字,姓氏等等。

所以,我希望能够从我的主表中提取所有记录并拥有相应的名字,并且最后根据主记录是员工,供应商还是司机。

主表中的一行对于员工

是这样的
EmployeeID = 352
VendorID = 0
DriverID=0

供应商看起来像

EmployeeID = 0
VendorID = 954
DriverID=0

帮助?

7 个答案:

答案 0 :(得分:4)

您可以使用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

即使有人设置了多个ID,这也会有效(在这种情况下,每个ID都会设置一行)。

您可能还想考虑是否值得更改架构以便于查询。你能将所有公共列移动到主表中吗?然后,您只需编写以下查询即可获得所需内容:

SELECT ID, Type, FirstName, LastName, ...
FROM mastertable

答案 1 :(得分:3)

你可能想要COALESCE,并且认为那些零id可能应该为null,但无论如何:

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

在思想的第二个分支上,如果一个人只能在三个中的一个中,这看起来像一个可疑的表设计,也许应该只有一个子表,但这取决于其他正在发生的事情。

答案 2 :(得分:2)

吉姆,

这可以通过联合和左连接到主表来完成,但我想建议您可以查看设计。供应商,员工和司机似乎都是人 - 包括名字,姓氏,地址,电话号码等等。似乎“人”表适合保存所有这些信息,并附加表格,用于存储特定于其各自角色的信息。

然后,您的主表可以具有personID字段以加入通用人员信息,以及可以与特定于角色的数据绑定的ID的另一个字段。

如果您对此有所了解,请告诉我。有关您的设计需求的更多信息,我们可以深入挖掘。

答案 3 :(得分:0)

你可以使用Left Joins和case语句来做到这一点,但维护起来会很糟糕。

我建议您为员工,供应商和驱动程序编写选择查询,然后使用Union来连接结果并将整个内容包装到视图中。

答案 4 :(得分:0)

这假设其他两个id字段对于特定类型为空:

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

您还可以重新设计主类型以获得PersonType字段,并存储单个ID,从而避免此设计中固有的稀疏数据。

答案 5 :(得分:0)

这有效:

SELECT(m.CustId> 0时的情况,然后c.FirstName,当m.EmpId> 0然后是emp.FirstName结束时的情况)作为FirstName,* FROM MAster m     左加入员工emp ON m.EmpId = emp.EmpId     左连接客户c ON m.CustId = c.CustIdster表到所有详细信息表的联盟

答案 6 :(得分:0)

我不是为什么需要这种设计的原因。但即使单行同时将EmplyeeID和VendorID都设置为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