📊 SQL для новачків

Вивчайте базові та середні SQL запити крок за кроком

Базові SQL запити

SELECT Basic

Вибір даних з таблиці

Як використовувати:
SELECT * FROM users;
SELECT name, email FROM users;
Що робить:

* означає "всі колонки". Перший запит вибирає всі дані, другий - тільки ім'я та email.

WHERE Basic

Фільтрація даних за умовою

Як використовувати:
SELECT * FROM users WHERE age > 18;
SELECT * FROM products WHERE price < 100;
Що робить:

Вибирає тільки записи, які відповідають умові. Операції: =, !=, >, <, >=, <=, LIKE.

ORDER BY Basic

Сортування результатів

Як використовувати:
SELECT * FROM users ORDER BY age ASC;
SELECT * FROM products ORDER BY price DESC;
Що робить:

ASC - від меньшого до більшого, DESC - від більшого до меньшого. За замовчуванням ASC.

LIMIT Basic

Обмеження кількості результатів

Як використовувати:
SELECT * FROM users LIMIT 10;
SELECT * FROM users LIMIT 10 OFFSET 20;
Що робить:

Показує тільки перші 10 записів. OFFSET 20 пропускає перші 20 записів (для пагінації).

DISTINCT Basic

Вибір унікальних значень

Як використовувати:
SELECT DISTINCT country FROM users;
SELECT DISTINCT city, country FROM users;
Що робить:

Видаляє дублікати. Якщо 100 користувачів з однієї країни, покажу країну один раз.

AND / OR Basic

Комбінування умов

Як використовувати:
SELECT * FROM users WHERE age > 18 AND country = 'Ukraine';
SELECT * FROM products WHERE price < 50 OR brand = 'Apple';
Що робить:

AND - обидві умови мають бути правдиві. OR - хоча б одна з умов має бути правдивою.

JOIN - Об'єднання таблиць

INNER JOIN Join

Перетин даних з двох таблиць

Як використовувати:
SELECT users.name, orders.total
FROM users
INNER JOIN orders ON users.id = orders.user_id;
Що робить:

Показує тільки записи, які є в обох таблицях. Якщо користувача немає в orders, його не буде в результаті.

LEFT JOIN Join

Всі записи з лівої таблиці

Як використовувати:
SELECT users.name, orders.total
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
Що робить:

Показує всіх користувачів, навіть тих, які не мають замовлень. Для них orders.total буде NULL.

RIGHT JOIN Join

Всі записи з правої таблиці

Як використовувати:
SELECT users.name, orders.total
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
Що робить:

Протилежність LEFT JOIN. Показує всі замовлення, навіть якщо користувача немає.

FULL JOIN Join

Всі записи з обох таблиць

Як використовувати:
SELECT users.name, orders.total
FROM users
FULL JOIN orders ON users.id = orders.user_id;
Що робить:

Комбінує LEFT та RIGHT JOIN. Показує всі користувачи та всі замовлення. Деякі поля можуть бути NULL.

Multiple JOINs Join

Об'єднання 3+ таблиць

Як використовувати:
SELECT users.name, orders.total, products.title
FROM users
JOIN orders ON users.id = orders.user_id
JOIN products ON orders.product_id = products.id;
Що робить:

Об'єднує кілька таблиць разом. Кожен JOIN додає нову таблицю та умову з'єднання.

Агрегуючі функції

COUNT() Aggregation

Підрахунок кількості записів

Як використовувати:
SELECT COUNT(*) FROM users;
SELECT COUNT(DISTINCT country) FROM users;
Що робить:

Першим запитом рахує всіх користувачів. Другим - кількість унікальних країн.

SUM() Aggregation

Сума значень

Як використовувати:
SELECT SUM(total) FROM orders;
SELECT SUM(price * quantity) FROM cart_items;
Що робить:

Додає всі значення колонки. Приклад: загальна сума всіх замовлень.

AVG() Aggregation

Середнє значення

Як використовувати:
SELECT AVG(price) FROM products;
SELECT AVG(age) FROM users WHERE country = 'Ukraine';
Що робить:

Розраховує середнє значення. Приклад: середня ціна товару чи середній вік.

MAX() / MIN() Aggregation

Максимальне та мінімальне значення

Як використовувати:
SELECT MAX(price) FROM products;
SELECT MIN(age) FROM users;
SELECT MAX(salary), MIN(salary) FROM employees;
Що робить:

MAX - найбільше значення, MIN - найменше значення. Приклад: найдорожчий та найдешевший товар.

GROUP BY Aggregation

Групування результатів

Як використовувати:
SELECT country, COUNT(*) as user_count
FROM users
GROUP BY country;

SELECT category, AVG(price) as avg_price
FROM products
GROUP BY category;
Що робить:

Групує дані за вказаною колонкою, потім застосовує агрегуючу функцію до кожної групи.

HAVING Aggregation

Фільтрація групованих результатів

Як використовувати:
SELECT country, COUNT(*) as user_count
FROM users
GROUP BY country
HAVING COUNT(*) > 10;

SELECT category, SUM(sales) as total_sales
FROM products
GROUP BY category
HAVING SUM(sales) > 1000;
Що робить:

WHERE працює на отримані дані, HAVING - на результати GROUP BY. Фільтрує групи за умовою.

Середні SQL команди

UNION Advanced

Об'єднання результатів двох запитів

Як використовувати:
SELECT name FROM customers
UNION
SELECT name FROM employees;

SELECT email FROM users
UNION ALL
SELECT email FROM admins;
Що робить:

UNION видаляє дублікати, UNION ALL залишає всі. Корисно для об'єднання даних з різних таблиць.

Subquery Advanced

Запит всередину запиту

Як використовувати:
SELECT name FROM users
WHERE id IN (
  SELECT user_id FROM orders
  WHERE total > 100
);

SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products);
Що робить:

Вкладений запит розраховується спочатку, потім його результат використовується у зовнішньому запиті.

CASE WHEN Advanced

Умовна логіка в запиті

Як використовувати:
SELECT name,
  CASE
    WHEN age < 18 THEN 'Minor'
    WHEN age < 65 THEN 'Adult'
    ELSE 'Senior'
  END as age_group
FROM users;
Що робить:

IF-THEN-ELSE логіка в SQL. Дозволяє створювати нові колонки на основі умов.

INSERT Advanced

Додавання нових записів

Як використовувати:
INSERT INTO users (name, email, age)
VALUES ('John', 'john@example.com', 25);

INSERT INTO users (name, email)
VALUES 
  ('Alice', 'alice@example.com'),
  ('Bob', 'bob@example.com');
Що робить:

Додає новий рядок у таблицю. Можна додати один або кілька записів одразу.

UPDATE Advanced

Оновлення існуючих даних

Як використовувати:
UPDATE users SET age = 30 WHERE id = 5;

UPDATE products SET price = price * 1.1
WHERE category = 'Electronics';
Що робить:

Змінює дані в існуючих записах. БЕЗ WHERE буде оновлено ВСІ записи!

DELETE Danger

Видалення записів

Як використовувати:
DELETE FROM users WHERE id = 5;

DELETE FROM logs WHERE created_at < '2020-01-01';
Що робить:

Видаляє записи з таблиці. БЕЗ WHERE видалить ВСІ записи! Завжди перевіряйте запит!

Практичні приклади

📊 Приклад 1: Статистика по країнам

SELECT 
  country,
  COUNT(*) as total_users,
  AVG(age) as avg_age,
  MAX(age) as oldest_user
FROM users
WHERE age > 18
GROUP BY country
HAVING COUNT(*) > 5
ORDER BY total_users DESC;

Що показує: Кількість користувачів старше 18 років по країнам, їхній середній вік та найстарший користувач. Тільки країни з 5+ користувачами.

💰 Приклад 2: Топ товарів за продажами

SELECT 
  p.title,
  COUNT(o.id) as times_ordered,
  SUM(o.quantity) as total_sold
FROM products p
LEFT JOIN order_items o ON p.id = o.product_id
GROUP BY p.id, p.title
HAVING SUM(o.quantity) > 10
ORDER BY total_sold DESC
LIMIT 10;

Що показує: Топ 10 товарів за кількістю проданих одиниць. Тільки товари з продажами > 10.

👥 Приклад 3: Активні користувачи

SELECT 
  u.name,
  u.email,
  COUNT(o.id) as order_count,
  SUM(o.total) as total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
GROUP BY u.id, u.name, u.email
HAVING COUNT(o.id) > 0
ORDER BY total_spent DESC;

Що показує: Активні користувачи з замовленнями та статистика по їхніх покупках.

🔍 Приклад 4: Користувачи без замовлень

SELECT u.id, u.name, u.email
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL
ORDER BY u.created_at DESC;

Що показує: Користувачи, які ніколи не зробили жодного замовлення.

📈 Приклад 5: Порівняння з максимальною ціною

SELECT 
  id,
  title,
  price,
  (SELECT MAX(price) FROM products) as max_price,
  ((SELECT MAX(price) FROM products) - price) 
    as price_diff
FROM products
ORDER BY price DESC;

Що показує: Товари з різницею їхної ціни від максимальної.

🎯 Приклад 6: Категоризація за ціною

SELECT 
  id,
  title,
  price,
  CASE
    WHEN price < 50 THEN 'Budget'
    WHEN price < 200 THEN 'Mid-range'
    WHEN price < 1000 THEN 'Premium'
    ELSE 'Luxury'
  END as price_segment
FROM products
ORDER BY price DESC;

Що показує: Товари розділені на ціневі сегменти за CASE WHEN.