Към съдържанието
wannacode

LEFT JOIN: и редовете без двойка

Накратко: LEFT JOIN пази всички редове на лявата таблица, дори тези без двойка в дясната, и попълва липсващите колони с NULL.

Проблем

Кой не е поръчал?

Маркетингът иска да пише на клиентите, които са се регистрирали, но още нищо не са поръчали. В миналия урок JOIN върна 60 реда и в тях Теодора и Явор ги нямаше.

JOIN пази само двойките. Ред без двойка изчезва без предупреждение. Тук точно тези редове ни трябват.

Идеята

LEFT JOIN

Сравни двете заявки. Първата е с JOIN:

SQLбаза: магазин

Втората е с LEFT JOIN:

SQLбаза: магазин

62 реда вместо 60. LEFT JOIN пази всеки ред на лявата таблица (тази във FROM), дори да няма двойка в дясната. Където двойка няма, колоните на дясната таблица са NULL. Слез до края: Теодора и Явор са там, с NULL за номера и датата.

Оттук клиентите без поръчки са на една крачка:

SQLбаза: магазин

WHERE o.id IS NULL оставя само редовете, при които поръчка не е намерена. Проверяваме o.id, защото първичният ключ на намерена поръчка никога не е празен.

Виж го

Празният отговор също е отговор

Има ли продукти, които никой не е поръчвал? Същият подход, с order_items:

SQLбаза: магазин

Нито един ред. Всеки от 25-те продукта е поръчан поне веднъж. Таблица без редове не е грешка: заявката е отговорила „няма такива“.

Пробвай

Празните категории

Кои категории нямат нито един продукт пряко в тях? Покажи името на категорията.

SQLбаза: магазин

Виж го

Броят с нулите

Колко поръчки има всеки клиент, заедно с тези без поръчки? Първи опит с COUNT(*):

SQLбаза: магазин

Теодора и Явор имат по 1 поръчка? Не. COUNT(*) брои редове, а LEFT JOIN им даде по един ред, пълен с NULL. Брой това, което има стойност, COUNT(o.id):

SQLбаза: магазин

COUNT(колона) пропуска NULL-ите, затова за тях излиза 0. При LEFT JOIN брой колона от дясната таблица, най-добре първичния ѝ ключ.

Пробвай

Отзивите на продуктите

Покажи всеки продукт и колко отзива има, включително продуктите без отзив (с 0).

SQLбаза: магазин

Виж го

Капанът с WHERE

Отчет за октомври: всички клиенти и колко поръчки са направили от 1 октомври 2026 г. Условието за датата отива в WHERE:

SQLбаза: магазин
1. Защо WHERE o.ordered_at >= … махна клиентите без поръчки през октомври?

Пет реда, а клиентите са 20. Условие за дясната таблица в WHERE превръща LEFT JOIN в обикновен JOIN. Мястото му е в ON: така то казва кои поръчки да се свържат, а клиентите остават всичките.

SQLбаза: магазин

20 клиенти, повечето с 0. Правилото: условие за дясната таблица при LEFT JOIN пишеш в ON. Изключение е IS NULL, когато търсиш липсващите.

Упражнение

Две задачи

1. Магазинът ще кани за отзив клиентите, които още не са писали. Кои са те? Покажи името.

Клиентите без нито един отзив:

SQLбаза: магазин

2. Кампанията „Липсваш ни“ е за клиентите, които нямат поръчка от 1 юли 2026 г. насам (включително тези, които никога не са поръчвали). Покажи името и имейла.

Клиентите без поръчка от 2026-07-01 насам:

SQLбаза: магазин
По-точно, за любопитните

Има и RIGHT JOIN (пази редовете на дясната таблица) и FULL JOIN (пази и двете страни). SQLite ги разбира от версия 3.39. RIGHT JOIN се пише рядко: същото е LEFT JOIN с разменени таблици. MySQL няма FULL JOIN.

SQLбаза: магазин

Тук излизат само клиентите без поръчки, защото всяка поръчка има клиент.

Тест

Провери се

1. FROM customers c LEFT JOIN orders o … Кои клиенти излизат?
2. Как се намират клиентите без поръчки?
3. Клиент без поръчки, LEFT JOIN и GROUP BY. Какво дава COUNT(*) за него?
4. Искаш всички клиенти и поръчките им само от октомври. Къде е условието за датата?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·