2011-01-21 5 views
2

У меня есть четыре таблицы один мастер таблица, которая содержит столбцы для EmployeeID, VendorID и DriverIDSQL Server 2008 РЕГИСТРИРУЙТЕСЬ Вопрос

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

Итак, я хочу, чтобы иметь возможность извлекать все записи из моей основной таблицы и иметь соответствующее имя и последнее, основанное на том, является ли основная запись сотрудником, продавцом или Водитель.

Строка в главной таблице хотел бы это для сотрудника

EmployeeID = 352 
VendorID = 0 
DriverID=0 

Поставщик будет выглядеть

EmployeeID = 0 
VendorID = 954 
DriverID=0 

т.д.

Помощь?

+3

ли вы когда-нибудь мастер-запись, которая может иметь два из них (или все три)? Если нет, я бы сказал, что ваша модель базы данных не нормализована и причина, по которой у вас возникают проблемы с запросом. – Oded

ответ

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 

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

Возможно, вам также стоит подумать, стоит ли менять схему, чтобы упростить ее запрос. Не могли бы вы переместить все общие столбцы в главную таблицу? Затем вам нужно будет только написать следующий запрос, чтобы получить то, что вы хотите:

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

Спасибо, это был ответ, который мне нужен –

0

Вы могли бы сделать это, используя левое Соединение и заявление случае, но это было бы ужасно, чтобы поддержать.

Я предлагаю вам написать отдельные запросы для сотрудников, поставщиков и драйверов, а затем использовать союз, чтобы объединить результаты и перенести все это на представление.

3

Вы, вероятно, хотите COALESCE, и мнится мне те нулевой идентификаторами возможно должен быть пустым, но в любом случае:

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 

Это предполагает, что человек будет только один из трех.

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

0

Это предполагает, что другие два поля идентификаторов равно нулем для конкретного типа:

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 и сохранить единый идентификатор, избегая разреженные данные присущими в этом дизайне.

2

Джим,

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

В вашей мастер-таблице может быть поле для идентификатора personID для объединения информации об общих лицах и другое поле (-и) для идентификатора, который может привязывать данные роли.

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

0

Это работает:

SELECT (случай, когда m.CustId> 0, то c.FirstName еще случай, когда m.EmpId> 0, то emp.FirstName конец конец), как FirstName, * FROM Хозяйский м Left Регистрация Employee emp ON m.EmpId = emp.EmpId Слева Присоединиться к клиенту c ON m.CustId = c.CustIdster table к Союзу всех таблиц подробностей

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