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

JOIN: две таблици в една заявка

Накратко: JOIN … ON слепва реда на едната таблица с реда на другата, към който сочи външният ключ, например поръчката с клиента ѝ, и оставя само редовете, които имат двойка.

Проблем

Поръчките с имената

Куриерската фирма иска списък: номер на поръчката, дата и името на клиента. Номерът и датата са в orders, името е в customers.

В миналия урок го правихме с две заявки и числото между тях го пренасяхме на ръка. За 60 поръчки това са 60 търсения. Трябва ни една заявка, която сама намира клиента на всяка поръчка.

Идеята

JOIN … ON

JOIN слага до всеки ред на едната таблица реда от другата, който му отговаря. ON казва кой ред на кой отговаря:

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

За всяка поръчка базата търси клиента, чието customers.id е равно на orders.customer_id, и ги слепва в един ред. Затова колоните се пишат с името на таблицата отпред: orders.id, customers.name.

Излизат 60 реда, колкото са поръчките: всяка поръчка има точно един клиент. Това се казва JOIN (или INNER JOIN): остават само двойките, които се намират. Теодора и Явор ги няма в списъка, защото нямат поръчки. Към тях ще се върнем в следващия урок.

На малки таблици се вижда как става: четири поръчки и трима клиенти, от които Теодора е без поръчки.

SELECT orders.id, orders.customer_id, customers.name
FROM orders
JOIN customers ON customers.id = orders.customer_id;
Стъпка по стъпка, с думи
  1. 4 поръчки и 3 клиента. customer_id на поръчката е id на нейния клиент.
  2. Поръчка 1 има customer_id 2. Базата търси клиента с id 2: Георги Петров. Двойката става ред.
  3. Поръчка 2: customer_id 1, това е Мария Иванова.
  4. Поръчка 3 е пак на клиент 1: Мария Иванова е в резултата втори път.
  5. Поръчка 4 е пак на клиент 2: Георги Петров е в резултата втори път.
  6. Теодора Генова (id 3) не е customer_id на нито една поръчка. Няма двойка, затова я няма в резултата.
  7. 4 реда, колкото са поръчките. JOIN оставя само двойките, които се намират.

Същата заявка върху тези малки таблици. Пусни я и сравни с последната стъпка:

SQLпразна база

Идеята

Кратки имена

orders.ordered_at и customers.name стават дълги. На таблицата може да се даде кратко име за заявката: пишеш го след името ѝ във FROM и JOIN.

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

Същата заявка, същият резултат. o е orders, c е customers. Краткото име важи само в тази заявка. Може да пишеш и FROM orders AS o.

Пробвай

Новите поръчки

Покажи номера на новите поръчки (status е new) с името и имейла на клиента, за да им се изпрати потвърждение.

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

Виж го

„ambiguous column name“

Ето заявка без имената на таблиците. Пусни я:

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

И orders, и customers имат колона id. След JOIN колоните на двете са заедно и базата не знае за коя id говориш. „Ambiguous“ значи „двусмислено“. Колоната name я има само в customers, затова за нея не се оплаква.

Решението е да кажеш от коя таблица е колоната:

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

Добрият навик е да пишеш краткото име пред всяка колона в заявка с JOIN, дори когато не е задължително. Който я чете, веднага вижда откъде е всяка колона.

Идеята

JOIN, WHERE и ORDER BY

След JOIN всичко познато работи както досега, а условията може да са върху колони и от двете таблици. Поръчките на клиентите от Варна, по дата:

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

Градът е в customers, датата е в orders. Редът на частите е: SELECT … FROM … JOIN … ON … WHERE … ORDER BY.

Пробвай

Какво има в поръчка 60

Покажи името на продукта, броя и цената за всеки ред на поръчка 60.

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

Упражнение

Две задачи

1. Магазинът проверява защо се отказват поръчки. Покажи номера на отказаните поръчки (cancelled) с името и града на клиента.

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

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

2. Отделът за качество иска отзивите с оценка 3 или по-ниска заедно с името на продукта, за да знае какво да провери.

Ниските оценки: продуктът, оценката и текстът на отзива:

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

Ще срещнеш и по-стария запис: таблиците във FROM със запетая, а условието за двойките в WHERE.

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

Резултатът е същият. Записът с JOIN … ON държи условието за свързване отделно от условията за филтриране. Затова в курса пишем JOIN.

Тест

Провери се

1. Какво казва ON c.id = o.customer_id?
2. Защо SELECT id FROM orders JOIN customers … дава „ambiguous column name: id“?
3. В заявката FROM orders o JOIN customers c какво е o?
4. Къде отива WHERE в заявка с JOIN?

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