SQL JOIN е клауза, която се използва за комбиниране на множество таблици и извличане на данни въз основа на общо поле в релационни бази данни. Специалистите по бази данни използват нормализации за осигуряване и подобряване на целостта на данните. В различните форми за нормализиране данните се разпределят в множество логически таблици. Тези таблици използват референтни ограничения – първичен ключ и външни ключове – за налагане на целостта на данните в таблиците на SQL Server. На изображението по-долу виждаме процеса на нормализиране на базата данни.
Разбиране на различните типове SQL JOIN
SQL JOIN генерира значими данни чрез комбиниране на множество релационни таблици. Тези таблици са свързани с помощта на ключ и имат връзки едно към едно или едно към много. За да извлечете правилните данни, трябва да знаете изискванията за данни и правилните механизми за присъединяване. SQL Server поддържа множество обединения и всеки метод има специфичен начин за извличане на данни от множество таблици. Изображението по-долу указва поддържаните присъединявания към SQL Server.
SQL вътрешно присъединяване
Вътрешното свързване на SQL включва редове от таблиците, където условията за присъединяване са удовлетворени. Например в диаграмата на Venn по-долу вътрешното свързване връща съвпадащите редове от таблица A и таблица B.
В примера по-долу забележете следните неща:
- Имаме две таблици – [Служители] и [Адрес].
- SQL заявката се обединява в колоните [Служители].[EmpID] и [Адрес].[ID].
Изходът на заявката връща записите на служителите за EmpID, които съществуват и в двете таблици.
Вътрешното съединение връща съвпадащи редове от двете таблици; следователно е известен още като Equi join. Ако не посочим вътрешна ключова дума, SQL Server изпълнява операцията за вътрешно присъединяване.
При друг тип вътрешно свързване, тета присъединяване, ние не използваме оператора за равенство (=) в клаузата ON. Вместо това използваме оператори, които не са за равенство, като <и>.
ИЗБЕРЕТЕ * ОТ Таблица1 T1, Таблица2 T2 КЪДЕТО T1.Цена
При самостоятелно присъединяване SQL Server се присъединява към таблицата със себе си. Това означава, че името на таблицата се появява два пъти в клаузата from.
По-долу имаме таблица [Emp], която съдържа служители, както и данни на техните мениджъри. Самоприсъединяването е полезно за запитване на йерархични данни. Например в таблицата на служителите можем да използваме самостоятелно присъединяване, за да научим всеки служител и името на неговия мениджър за отчитане.
Горната заявка поставя самостоятелно присъединяване към таблицата [Emp]. Той свързва колоната EmpMgrID с колоната EmpID и връща съвпадащите редове.
При кръстосаното свързване SQL Server връща декартов продукт от двете таблици. Например в изображението по-долу извършихме кръстосано свързване за таблица А и Б.
Кръстосаното свързване свързва всеки ред от таблица A с всеки ред, наличен в таблица B. Следователно изходът е известен също като декартово произведение на двете таблици. В изображението по-долу обърнете внимание на следното:
В изхода за кръстосано свързване, ред 1 от таблицата [Служител] се съединява с всички редове на таблицата [Address] и следва същия модел за останалите редове.
Ако първата таблица има x брой редове, а втората таблица има n брой редове, кръстосаното свързване дава x*n брой редове в изхода. Трябва да избягвате кръстосано свързване на по-големи таблици, защото може да върне огромен брой записи и SQL Server изисква много изчислителна мощност (CPU, памет и IO) за обработка на толкова обширни данни.
Както обяснихме по-рано, вътрешното свързване връща съвпадащите редове от двете таблици. Когато се използва външно SQL присъединяване, то не само изброява съвпадащите редове, но също така връща несъвпадащите редове от другите таблици. Несъответстващият ред зависи от левите, дясните или пълните ключови думи.
Изображението по-долу описва на високо ниво лявото, дясното и пълното външно съединение.
SQL лявото външно присъединяване връща съвпадащите редове от двете таблици заедно с несъответстващите редове от лявата таблица. Ако запис от лявата таблица няма съвпадащи редове в дясната таблица, той показва записа със стойности NULL.
В примера по-долу лявото външно съединение връща следните редове:
Дясното външно присъединяване на SQL връща съвпадащите редове от двете таблици заедно с несъответстващите редове от дясната таблица. Ако запис от дясната таблица няма съвпадащи редове в лявата таблица, той показва записа със стойности NULL.
В примера по-долу имаме следните изходни редове:
Пълно външно присъединяване връща следните редове в изхода:
В предишните примери използваме две таблици в SQL заявка за извършване на операции за присъединяване. Най-често ние свързваме няколко таблици заедно и това връща съответните данни.
Заявката по-долу използва множество вътрешни съединения.
Нека анализираме заявката в следните стъпки:
След като изпълните заявката с множество обединения, оптимизаторът на заявки подготвя плана за изпълнение. Той подготвя оптимизиран за разходите план за изпълнение, удовлетворяващ условията за присъединяване с използването на ресурса – например в долния действителен план за изпълнение можем да разгледаме множество вложени цикли (вътрешно присъединяване) и хеш съвпадение (вътрешно присъединяване), комбиниращи данни от множество свързващи таблици .
Да предположим, че имаме NULL стойности в колоните на таблицата и се присъединяваме към таблиците в тези колони. SQL Server отговаря ли на NULL стойности?
NULL стойностите не съвпадат една с друга. Следователно SQL Server не може да върне съответстващия ред. В примера по-долу имаме NULL в колоната EmpID на таблицата [Служители]. Следователно в изхода той връща съответстващия ред само за [EmpID] 2.
Можем да получим този NULL ред в изхода в случай на SQL външно присъединяване, защото той връща и несъвпадащите редове.
В тази статия проучихме различните типове SQL присъединяване. Ето няколко важни най-добри практики, които трябва да запомните и приложите, когато използвате SQL съединения.Самоприсъединяване към SQL
SQL кръстосано присъединяване
SQL външно присъединяване
Ляво външно съединение
Дясно външно съединение
Пълно външно присъединяване
SQL се свързва с множество таблици
USE [AdventureWorks2019]
GO
SELECT
e.[BusinessEntityID]
,p.[FirstName]
,p.[MiddleName]
,p.[LastName]
,e.[JobTitle]
,d.[Name] AS [Department]
,d.[GroupName]
,edh.[StartDate]
FROM [HumanResources].[Employee] e
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = e.[BusinessEntityID]
INNER JOIN [HumanResources].[EmployeeDepartmentHistory] edh
ON e.[BusinessEntityID] = edh.[BusinessEntityID]
INNER JOIN [HumanResources].[Department] d
ON edh.[DepartmentID] = d.[DepartmentID]
WHERE edh.EndDate IS NULL
GO
NULL стойности и SQL съединения
Най-добри практики за присъединяване към SQL