2015-02-17 4 views
0

Это будет немного сложно. Позвольте мне начать с моих столов.захват информации путем объединения нескольких таблиц

clients [src = 0] 
--------- 
clientID  code   company 
---------  -------  --------- 
1    ABC   ABC Corp 
2    DEF   DEF Corp 


carriers [src = 1] 
--------- 
clientID  code  company 
---------  ------- ------- 
1    ABC   ABC Inc. 
2    JHI   JHI Inc. 


link 
-------- 
contactID  uID  src 
---------  ----- ---- 
1     1  0 
1     1  1 
1     2  0 

contact info 
-------------- 
contactID  fname  lname 
---------  -------  -------- 
1    John  Smith 
2    Quincy  Jones 

Итак, я пытаюсь выполнить поиск для «ABC» в таблице ссылок. Таблица ссылок должна в основном присоединиться к таблице операторов или клиентов в зависимости от столбца link.src. Он должен найти два совпадения: один в клиентах и ​​один в перевозчиках, но так как оба разрешают contactID (таблица ссылок) 1, я должен затем запросить контактную информацию и вернуть

Найдено 1 записей (ов): John Smith

Надеюсь, это имеет смысл. Любая помощь очень ценится!

+0

Каков желаемый результат, если два найденных совпадения не разрешены к одному и тому же 'contactID'? Что делать, если найден только один матч? –

+0

В ссылке tbl они оба имеют контакт 1 – Damien

+0

Что делать, если у одного был «контактID = 1», тогда как другой матч имел «contactID = 2», или этот случай не считается возможным? –

ответ

2

Вот один подход с использованием left join:

select co.* 
from link l left join 
    clients cl 
    on l.src = 0 and l.uid = cl.code left join 
    carriers ca 
    on l.src = 1 and l.uid = ca.code left join 
    contacts co 
    on l.contactid = co.contactid 
where 'ABC' in (co.code, cl.code) 
+0

не так ли? – Damien

+0

клиентов c ON l.src = 0 И l.uID = cl.clientID? – Damien

+0

@Damien. , , Спасибо. Это похоже на правильное имя столбца. –

0

Вот другой подход. Сначала вы найдете UNION таблицы Clients и Carriers и добавьте новый столбец ContactType, чтобы различать один от другого. Используйте 0 для Clients и 1 для Carriers, то же, что и src. Затем вы получите LEFT JOIN, чтобы получить желаемый результат.

;WITH Clients(ClientID, Code, Company) AS(
    SELECT 1, 'ABC', 'ABC Corp' UNION ALL 
    SELECT 2, 'DEF', 'DEF Corp' 
) 
,Carriers(ClientID, Code, Company) AS(
    SELECT 1, 'ABC', 'ABC Inc.' UNION ALL 
    SELECT 2, 'JHI', 'JHI Inc.' 
) 
,Link(ContactId, UID, Src) AS(
    SELECT 1, 1, 0 UNION ALL 
    SELECT 1, 1, 1 UNION ALL 
    SELECT 1, 2, 0 
) 
,ContactInfo(ContactID, FName, LName) AS(
    SELECT 1, 'John', 'Smith' UNION ALL 
    SELECT 2, 'Quincy', 'Jones' 
) 
-- START 
,Contact(ContactID, ContactType, Code, Company) AS(
    SELECT 
     ClientID, 0, Code, Company 
    FROM Clients 
    UNION ALL 
    SELECT 
     ClientID, 1, Code, Company 
    FROM Carriers 
) 
SELECT DISTINCT 
    ci.FName, 
    ci.LName 
FROM Link l 
LEFT JOIN Contact c 
    ON c.ContactID = l.UID 
    AND c.ContactType = l.src 
LEFT JOIN ContactInfo ci 
    ON ci.ContactID = c.ContactID 
WHERE 
    c.Code = 'ABC' 
0

Посмотрите на это из модели pov. У вас есть две таблицы с одинаковым типом данных в каждом из них, предприятие компания. Единственная разница между ними - их роль или отношение к вашей компании. Так почему бы не держать их всех в одном ведре?

Companies: 
ID code Name 
-- ---- --------- 
1 ABC ABC Corp 
2 DEF DEF Corp 
3 JHI JHI Inc. 

Если конкретная компания может быть только клиент или носитель, что обозначение может быть помещен в компаний таблицы. Поскольку, очевидно, одна компания может быть обоим, обозначение переходит в отдельную таблицу. Ниже показано, что компания 1, «ABC», является клиентом («L») и перевозчиком («R»), компания 2 является только клиентом, а компания 3 является перевозчиком.

CompanyRoles: 
CompanyID Type 
--------- ---- 
     1 'L' 
     1 'R' 
     2 'L' 
     3 'R' 

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

Что касается контактов, если у компании есть один контакт независимо от роли, контактная информация может быть добавлена ​​к . Компании стол. Если контакт зависит от роли, он добавляется в таблицу CompanyRoles.

CompanyRoles: 
CompanyID Type ContactID 
--------- ---- --------- 
     1 'L'   1 
     1 'R'   2 
     2 'L'   3 
     3 'R'   4 

Хотите увидеть список клиентов?

select c.ID as ClientID, c.Code as ClientCode, c.Name as ClientName, 
     ci.ContactName 
from Companies c 
join CompanyRoles cr 
    on cr.CompanyID = c.ID 
    and cr.Type  = 'L' 
left join Contacts ct -- In case no contact is currently defined 
    on ct.ContactID = cr.ContactID 
join ClientSpecificData csd 
    on csd.ClientID = c.ID; 

Хотите увидеть список перевозчиков?

select c.ID as CarrierID, c.Code as CarrierCode, c.Name as CarrierName, 
     ci.ContactName 
from Companies c 
join CompanyRoles cr 
    on cr.CompanyID = c.ID 
    and cr.Type  = 'R' 
left join Contacts ct -- In case no contact is currently defined 
    on ct.ContactID = cr.ContactID 
join CarrierSpecificData csd 
    on csd.ClientID = c.ID; 

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

Как вы можете видеть, запросы являются чистыми и простыми. Целостность данных проста и масштабируемость не является проблемой. Чего еще можно хотеть?

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