Урок 4: Підзапити — Коли Одного Запиту Недостатньо!
Вітаю знову, сміливий досліднику даних! Якщо ти дійшов до цього моменту, ти, напевно, думаєш: “Та це ж все легко, як два байти переслати!” Але щойно ти вирішив, що став повноправним господарем своїх таблиць, PostgreSQL викидає на стіл нову карту: Підзапити. Ось тут і починається справжня магія. Підзапити — це такі маленькі шпигунські місії, приховані всередині основного запиту, які роблять всю брудну роботу за лаштунками.
Що Таке Підзапит?
Уяви, що ти в ресторані. Ти замовив собі піцу (основний запит), але тихо додаєш офіціанту: “До речі, якщо є можливість, покладіть зверху ще трохи сиру.” Оце і є твій підзапит! Підзапит — це запит, вкладений всередині іншого запиту, що використовується для уточнення або розширення результату основного запиту.
Підзапити корисні, коли одного запиту просто недостатньо, наприклад:
- Знайти найуспішніших лицарів (за кількістю виконаних завдань).
- Дізнатися, які дракони спалили більше трьох сіл.
- Визначити, які лицарі потребують, скажімо, додаткового тренування.
Типи Підзапитів
Підзапити бувають різних типів, залежно від того, як і де ти їх використовуєш. Знайомимося з головними героями:
- Однорядкові Підзапити: Повертають лише один рядок. Ідеальні для швидкого підглядання.
- Багаторядкові Підзапити: Повертають кілька рядків. Чудово підходять для порівняння списків!
- Скалярні Підзапити: Повертають одне значення. Круті для таємних порівнянь.
- Корельовані Підзапити: Це шпигуни — вони знають, що відбувається в основному запиті, і підлаштовуються на ходу.
А тепер погляньмо, як працюють ці підзапити!
Використання Підзапитів у SELECT
Почнемо з простого прикладу. Припустімо, у тебе є таблиця lytsari
і ти хочеш знати, який лицар виконав найбільше завдань:
SELECT imya
FROM lytsari
WHERE misyiyi_vykonano = (SELECT MAX(misyiyi_vykonano) FROM lytsari);
Цей маленький підзапит (SELECT MAX(misyiyi_vykonano) FROM lytsari)
робить свою роботу, повертає максимальне значення і передає його основному запиту, який каже: “Покажи мені лише тих лицарів, у яких стільки ж виконаних місій.”
Підзапити в FROM
А тепер, припустімо, ти хочеш згрупувати лицарів за королівством і подивитися середню кількість виконаних місій. Звичайний запит заплутається, але підзапит у FROM
легко впорається:
SELECT korolivstvo, AVG(misyiyi_vykonano)
FROM (SELECT imya, korolivstvo, misyiyi_vykonano FROM lytsari) AS sub_lytsari
GROUP BY korolivstvo;
Тут наш підзапит діє як тимчасова таблиця, обмежуючи дані, перш ніж основний запит почне їх обробляти.
Підзапити в WHERE
Підзапити часто використовуються в WHERE
для встановлення умов. Уяви, що хочеш знайти лицарів, які виконали більше місій, ніж середнє значення для всіх лицарів:
SELECT imya
FROM lytsari
WHERE misyiyi_vykonano > (SELECT AVG(misyiyi_vykonano) FROM lytsari);
Підзапит обчислює середнє значення, а основний запит каже: “Покажи мені тільки тих лицарів, які перевищують середній рівень!” (Ті, що не б’ють байдики, коротше кажучи.)
Корельовані Підзапити: Шпигуни SQL
Корельовані підзапити — це найбільш хитрі з усіх. Вони запускаються для кожного рядка основного запиту і можуть звертатися до його стовпців. Припустімо, ти хочеш дізнатися, які лицарі виконали більше завдань, ніж середній показник для їхнього королівства:
SELECT imya, korolivstvo
FROM lytsari AS c1
WHERE misyiyi_vykonano > (SELECT AVG(misyiyi_vykonano)
FROM lytsari AS c2
WHERE c2.korolivstvo = c1.korolivstvo);
Тут підзапит обчислює середню кількість місій для кожного королівства динамічно. Це як шпигун у головному запиті, який збирає інформацію і передає її далі.
Підзапити в SELECT
Нарешті, поговоримо про підзапити в SELECT
. Уяви, що хочеш звіт, який показує ім’я кожного лицаря і те, як він порівнюється із загальною середньою кількістю виконаних місій:
SELECT imya,
misyiyi_vykonano,
(SELECT AVG(misyiyi_vykonano) FROM lytsari) AS serednya_misyiy
FROM lytsari;
Тепер у тебе є чітке порівняння, і все це завдяки цьому маленькому підзапиту, що ховається у запиті основному.
Об’єднаємо Все Разом: Велике Шоу Підзапитів!
Ось сценарій, який покаже все, що ми дізналися:
Ти хочеш знайти лицарів, які виконали більше завдань, ніж середній рівень, але тільки якщо вони з королівств, де середня кількість місій перевищує 3. Здається складно? Ось магія:
SELECT imya
FROM lytsari
WHERE misyiyi_vykonano > (SELECT AVG(misyiyi_vykonano)
FROM lytsari)
AND korolivstvo IN (SELECT korolivstvo
FROM lytsari
GROUP BY korolivstvo
HAVING AVG(misyiyi_vykonano) > 3);
Цей монстр-запит використовує підзапити і в WHERE
, і в IN
умовах. Це як керувати цілою армією маленьких запитів!
Що Ми Сьогодні Вивчили?
Сьогодні ми дослідили світ підзапитів:
- Однорядкові Підзапити: Повертають один рядок, використовуються для точних порівнянь.
- Багаторядкові Підзапити: Повертають кілька рядків, ідеальні для списків.
- Скалярні Підзапити: Повертають одне значення, для порівнянь.
- Корельовані Підзапити: Динамічно підлаштовуються під основний запит.
Що Далі?
У наступному уроці ми дослідимо CTE та Віконні Функції. Приготуйся вивести свої навички SQL на новий рівень!
Ласкаво просимо у світ підзапитів. Хай твої запити завжди будуть акуратними, а результати — точ