Многоуровневые объединения SQL
Мне нужно объединить как минимум 4 таблицы. Таблица A является таблицей ассоциации, которая содержит руководство для таблиц B и C, Parentguid (B), Childguid (C). Таблица D содержит информацию только для таблицы C.
Мне нужны результаты, чтобы выглядеть так.
B - C - D
Монитор - Имя компьютера - Активно
Поэтому главное - показать всю таблицу B, только таблицу C, связанную с B, и только таблицу D, связанную с C.
Я подозреваю, что мне понадобятся присоединения (). Я все еще новичок, это имеет смысл в моей голове, но я не могу заставить код работать. Я играл с объединениями в течение последних 2 дней.
FROM vHWDesktopMonitor mon -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid
full outer join vComputer comp on RM.ChildResourceGuid = comp.Guid
full outer join vAsset on RM.ChildResourceGuid = vAsset._ResourceGuid
2 ответа
FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
on A._ResourceGuid = B.ParentResourceGuid
LEFT JOIN vComputer C
on B.ChildResourceGuid = C.Guid
LEFT JOIN vAsset D
on C.ChildResourceGuid = D._ResourceGuid
Так что выше вернется
- Все ОТ А и ВСЕ записи из B (полное внешнее между A, B)
- Только записи из C, которые находятся в B (слева между B и C)
- Только записи из D, которые находятся в C (ВЛЕВО между C и D)
Однако, если вы примените какие-либо ограничения условия where, это может уменьшить записи, которые в противном случае были бы сохранены из-за левого или внешнего соединения...
Например, если A._ResourceGuid ='7' существует в A, но не в B; и вы устанавливаете, где B._ResourceGuid ='7', в противном случае запись A будет сохранена, поскольку полное внешнее соединение будет исключено (делая полное внешнее соединение таким же, как INNER JOIN)!
полный внешний будет возвращать данные, как это:
A B
7 7
2
3
если вы добавите предложение where, где B=7, то вы, возможно, ожидаете получить из-за полного внешнего, так как вы сказали, что возвращают все записи из обоих... A B 7 7 2
Но вы бы в конечном итоге получить
A B
7 7
Потому что предложение where встречается ПОСЛЕ полного внешнего и, следовательно, уменьшает запись A.2. Чтобы компенсировать это, вы должны либо установить ограничения на соединение до полного выполнения внешнего кода, либо обработать его в предложении where (но этот метод ОЧЕНЬ грязный и подвержен ошибкам и проблемам с производительностью)
Таким образом, при использовании внешних объединений вы ДОЛЖНЫ установить критерии ограничения для самого СОЕДИНЕНИЯ, как показано ниже.
FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
on A._ResourceGuid = B.ParentResourceGuid
and B._resourceGuid = '7'
LEFT JOIN vComputer C
on B.ChildResourceGuid = C.Guid
LEFT JOIN vAsset D
on C.ChildResourceGuid = D._ResourceGuid
Вы также можете поместить его в предложение where, но не забывайте учитывать все внешние соединения в таблице и включать нулевые значения для других (это просто грязно и медленно).
FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
on A._ResourceGuid = B.ParentResourceGuid
LEFT JOIN vComputer C
on B.ChildResourceGuid = C.Guid
LEFT JOIN vAsset D
on C.ChildResourceGuid = D._ResourceGuid
WHERE (A._ResourceGuid is null OR B.ParentResourceGuid ='7')
Если я вас правильно понимаю, то любой из них должен работать
FROM vHWDesktopMonitor mon -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
left join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid
left join vComputer comp on RM.ChildResourceGuid = comp.Guid
left join vAsset on comp.Guid = vAsset._ResourceGuid
или же
FROM vHWDesktopMonitor mon -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
left join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid
left join (select [list fields here] from vComputer comp
join vAsset on comp.Guid = vAsset._ResourceGuid) comp2
on RM.ChildResourceGuid = comp2.Guid
это должно получить все записи из vHWDesktopMonitor и связанные с ним записи из ResourceAssociation с пустыми значениями для любых записей в vHWDesktopMonitor, но не в ResourceAssociation. Затем вы получаете все записи в vComputer, которые также находятся в ResourceAssociation. Наконец, вы получаете все записи в vAsset, которые находятся в vComputer. как правило, когда вы получаете все записи в первой таблице, там будут пустые целые поля из других таблиц, если у вас нет связанной записи.
Если это не сработает, возможно, вам нужно показать нам пример данных и ожидаемых результатов.