INNER JOIN to operator Transact-SQL zwracający wyłącznie wiersze mające dopasowanie w obu łączonych tabelach.
Jak INNER JOIN łączy wiersze w Transact-SQL
INNER JOIN w języku Transact-SQL służy do połączenia dwóch zbiorów wynikowych na podstawie warunku określonego po słowie kluczowym ON. Wynik zawiera tylko te wiersze z lewej i prawej tabeli, dla których warunek połączenia jest spełniony. Jeżeli tabela Klienci zawiera identyfikator klienta, a tabela Zamowienia przechowuje ten identyfikator przy każdym zamówieniu, połączenie obu tabel może wykorzystać relację między kolumnami Klienci.IdKlienta i Zamowienia.IdKlienta. Dane klienta zostaną wtedy pokazane wyłącznie dla klientów mających co najmniej jedno pasujące zamówienie.
W Transact-SQL można zapisać połączenie z użyciem składni INNER JOIN albo samego słowa JOIN, ponieważ w tym kontekście JOIN oznacza domyślnie połączenie wewnętrzne. Jawne wskazanie INNER JOIN bywa jednak czytelniejsze, szczególnie w zapytaniach zawierających kilka tabel. Każda tabela może otrzymać alias, dzięki czemu kolumny są jednoznacznie identyfikowane, na przykład k dla klientów i z dla zamówień. Jest to istotne, gdy obie tabele mają kolumny o tej samej nazwie, takie jak IdKlienta, Status albo DataUtworzenia.
Warunek ON, klucze i wartości NULL
Najczęściej warunek ON porównuje klucz główny jednej tabeli z kluczem obcym drugiej tabeli. Nie jest to jednak wymagane przez sam operator. Transact-SQL może łączyć wiersze także według kilku kolumn, zakresu wartości albo innych wyrażeń logicznych. Przy kluczu złożonym trzeba uwzględnić wszystkie kolumny tworzące relację. Pominięcie jednej z nich może spowodować połączenie wierszy, które mają zgodną tylko część identyfikatora, a w konsekwencji zwielokrotnienie lub zniekształcenie wyników.
Porównanie z użyciem operatora równości nie uznaje wartości NULL za równą innej wartości NULL. W praktyce wiersz, którego kolumna używana w warunku połączenia ma wartość NULL, nie zostanie dopasowany przez typowy warunek t1.Klucz = t2.Klucz. Wpływ na wynik ma również typ danych kolumn. SQL Server może wykonać niejawną konwersję typów, jeżeli jest ona dozwolona, lecz różnice typów mogą zwiększyć koszt zapytania albo doprowadzić do błędu konwersji. Przy porównywaniu danych tekstowych znaczenie mogą mieć także reguły sortowania, czyli collation, określające między innymi sposób traktowania wielkości liter i znaków diakrytycznych.
Różnica między INNER JOIN a filtrowaniem połączenia
Warunek relacji powinien zwykle znajdować się w klauzuli ON, natomiast ograniczenia dotyczące gotowego wyniku można umieścić w klauzuli WHERE. W przypadku INNER JOIN wiele warunków zapisanych w ON i WHERE może dać podobny rezultat, ponieważ i tak pozostają tylko dopasowane wiersze. Nie oznacza to jednak, że oba miejsca mają zawsze takie samo znaczenie. Czytelne rozdzielenie warunku łączącego tabele od warunków filtrujących ułatwia kontrolę zapytania i ogranicza ryzyko błędnej interpretacji logiki.
Ważnym problemem jest przypadkowe pomnożenie liczby wierszy. Jeżeli jeden klient ma trzy zamówienia, wynik połączenia klienta z zamówieniami będzie zawierał trzy wiersze dotyczące tego klienta. Jeżeli następnie każde zamówienie ma pozycje, połączenie z tabelą pozycji zwróci osobny wiersz dla każdej pozycji. Taki rezultat jest prawidłowy dla szczegółowego raportu, ale może zawyżyć sumy liczone bezpośrednio po połączeniu. Do kontroli struktury wyniku stosuje się między innymi COUNT, COUNT(DISTINCT ...), odpowiednie grupowanie przez GROUP BY oraz świadome określenie, czy raport ma przedstawiać dane na poziomie klienta, zamówienia czy pojedynczej pozycji.
Wydajność zapytania i praktyczna diagnostyka wyników
Optymalizator zapytań SQL Server dobiera plan wykonania dla zapytania zawierającego INNER JOIN. W planie może pojawić się między innymi zagnieżdżona pętla, łączenie przez scalanie albo łączenie haszujące. Wybór zależy od rozmiaru tabel, dostępnych indeksów, rozkładu wartości i szacowanej liczby pasujących wierszy. Indeks na kolumnie używanej do łączenia może ograniczyć liczbę odczytywanych danych, ale jego przydatność zależy od konkretnego zapytania i kolejności kolumn w indeksie. Samo dodanie indeksu nie gwarantuje poprawy, zwłaszcza gdy zapytanie zwraca znaczną część tabeli albo wymusza konwersję typów.
Przy diagnozowaniu nieoczekiwanego wyniku warto najpierw uruchomić zapytanie z ograniczoną listą kolumn i sprawdzić kilka konkretnych par kluczy. Następnie należy porównać liczbę wierszy przed połączeniem i po nim, sprawdzić duplikaty w kolumnach użytych jako identyfikator oraz potwierdzić, czy warunek ON obejmuje właściwe kolumny. Pomocne jest także obejrzenie rzeczywistego lub szacowanego planu wykonania oraz statystyk wejściowych, ponieważ plan może ujawnić skan dużej tabeli, nieoczekiwaną konwersję albo błędne oszacowanie liczby dopasowań. W zastosowaniach użytkowych poprawna interpretacja zapytania INNER JOIN ma znaczenie podczas analizy danych zapisanych na laptopie lub komputerze PC, zwłaszcza gdy niewłaściwe połączenie powoduje brak rekordów, ich powielanie albo błędne wartości raportu.