Урок 4: Підзапити — Коли Одного Запиту Недостатньо!


Lesson 4

Урок 4: Підзапити — Коли Одного Запиту Недостатньо!

Вітаю знову, сміливий досліднику даних! Якщо ти дійшов до цього моменту, ти, напевно, думаєш: “Та це ж все легко, як два байти переслати!” Але щойно ти вирішив, що став повноправним господарем своїх таблиць, PostgreSQL викидає на стіл нову карту: Підзапити. Ось тут і починається справжня магія. Підзапити — це такі маленькі шпигунські місії, приховані всередині основного запиту, які роблять всю брудну роботу за лаштунками.

Що Таке Підзапит?

Уяви, що ти в ресторані. Ти замовив собі піцу (основний запит), але тихо додаєш офіціанту: “До речі, якщо є можливість, покладіть зверху ще трохи сиру.” Оце і є твій підзапит! Підзапит — це запит, вкладений всередині іншого запиту, що використовується для уточнення або розширення результату основного запиту.

Підзапити корисні, коли одного запиту просто недостатньо, наприклад:

  • Знайти найуспішніших лицарів (за кількістю виконаних завдань).
  • Дізнатися, які дракони спалили більше трьох сіл.
  • Визначити, які лицарі потребують, скажімо, додаткового тренування.

Типи Підзапитів

Підзапити бувають різних типів, залежно від того, як і де ти їх використовуєш. Знайомимося з головними героями:

  1. Однорядкові Підзапити: Повертають лише один рядок. Ідеальні для швидкого підглядання.
  2. Багаторядкові Підзапити: Повертають кілька рядків. Чудово підходять для порівняння списків!
  3. Скалярні Підзапити: Повертають одне значення. Круті для таємних порівнянь.
  4. Корельовані Підзапити: Це шпигуни — вони знають, що відбувається в основному запиті, і підлаштовуються на ходу.

А тепер погляньмо, як працюють ці підзапити!

Використання Підзапитів у 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 на новий рівень!


Ласкаво просимо у світ підзапитів. Хай твої запити завжди будуть акуратними, а результати — точ