На практика WHERE
условия и JOIN
условия за [INNER] JOIN
са 100% еквивалентни в PostgreSQL. (Добра практика е да използвате изрично JOIN
условия, за да улеснят четенето и поддържането на заявките.
Същото е не true за LEFT JOIN
комбинирано с WHERE
условие на маса вдясно от съединението. Целта на LEFT JOIN
е да се запазят всички редове от лявата страна на съединението, независимо от съвпадение от дясната страна. Ако не бъде намерено съвпадение, редът се разширява с NULL
стойности за колони от дясната страна. Ръководството:
LEFT OUTER JOIN
Първо се извършва вътрешно свързване. След това, за всеки ред в T1, който не удовлетворява условието за свързване с който и да е ред в T2, се добавя присъединен ред с нулеви стойности в колоните на T2. Така обединената таблица винаги има поне един ред за всеки ред в T1.
Ако след това приложите WHERE
условие, което изисква нещо различно от NULL
стойност на колони от таблици от дясната страна, вие анулирате ефекта и принудително преобразувате LEFT [OUTER] JOIN
да работи като обикновен [INNER] JOIN
, просто (евентуално) по-скъпо поради по-сложен план за заявка.
При заявка с много свързани таблици, Postgres (или която и да е RDBMS) е трудно да намери най-добрия (или дори добър) план за заявка. Броят на теоретично възможните последователности за свързване на таблици нараства фактично (!). Postgres използва „Оптимизатор на общи заявки“ за задачата и има някои настройки, които да й повлияят.
Закриване на заявката с подвеждащ LEFT JOIN
както е посочено, затруднява работата на инструмента за планиране на заявки, подвеждащ е за човешките читатели и обикновено намеква за грешки в логиката на заявката.
Свързани отговори за проблеми, произтичащи от това:
- Защо null е равно на цяло число в WHERE?
- Заявка с LEFT JOIN не връща редове за брой от 0
- SQL заявка, използваща външно присъединяване и ограничаване на дъщерните записи за всеки родител
- Лявото външно съединение действа като вътрешно съединение
- Изберете редове, които не присъстват в друга таблица
И т.н.