Spaces:
Running
Running
| <html lang="uk"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>SQL для новачків - Навчальний дашборд</title> | |
| <link rel="stylesheet" href="styles-sql.css"> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <!-- Header --> | |
| <header class="header"> | |
| <div class="header-content"> | |
| <h1>📊 SQL для новачків</h1> | |
| <p class="subtitle">Вивчайте базові та середні SQL запити крок за кроком</p> | |
| </div> | |
| </header> | |
| <!-- Navigation Tabs --> | |
| <nav class="tabs"> | |
| <button class="tab-button active" data-tab="basic">Базові запити</button> | |
| <button class="tab-button" data-tab="joins">JOIN операції</button> | |
| <button class="tab-button" data-tab="aggregation">Агрегація</button> | |
| <button class="tab-button" data-tab="advanced">Середні команди</button> | |
| <button class="tab-button" data-tab="examples">Приклади</button> | |
| </nav> | |
| <!-- Main Content --> | |
| <main class="content"> | |
| <!-- Tab 1: Basic Queries --> | |
| <section id="basic" class="tab-content active"> | |
| <h2>Базові SQL запити</h2> | |
| <div class="commands-grid"> | |
| <!-- SELECT --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">SELECT</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Вибір даних з таблиці</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT * FROM users; | |
| SELECT name, email FROM users;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>* означає "всі колонки". Перший запит вибирає всі дані, другий - тільки ім'я та email.</p> | |
| </div> | |
| </div> | |
| <!-- WHERE --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">WHERE</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Фільтрація даних за умовою</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT * FROM users WHERE age > 18; | |
| SELECT * FROM products WHERE price < 100;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Вибирає тільки записи, які відповідають умові. Операції: =, !=, >, <, >=, <=, LIKE.</p> | |
| </div> | |
| </div> | |
| <!-- ORDER BY --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">ORDER BY</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Сортування результатів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT * FROM users ORDER BY age ASC; | |
| SELECT * FROM products ORDER BY price DESC;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>ASC - від меньшого до більшого, DESC - від більшого до меньшого. За замовчуванням ASC.</p> | |
| </div> | |
| </div> | |
| <!-- LIMIT --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">LIMIT</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Обмеження кількості результатів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT * FROM users LIMIT 10; | |
| SELECT * FROM users LIMIT 10 OFFSET 20;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Показує тільки перші 10 записів. OFFSET 20 пропускає перші 20 записів (для пагінації).</p> | |
| </div> | |
| </div> | |
| <!-- DISTINCT --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">DISTINCT</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Вибір унікальних значень</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT DISTINCT country FROM users; | |
| SELECT DISTINCT city, country FROM users;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Видаляє дублікати. Якщо 100 користувачів з однієї країни, покажу країну один раз.</p> | |
| </div> | |
| </div> | |
| <!-- AND/OR --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">AND / OR</code> | |
| <span class="badge basic">Basic</span> | |
| </div> | |
| <p class="description">Комбінування умов</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT * FROM users WHERE age > 18 AND country = 'Ukraine'; | |
| SELECT * FROM products WHERE price < 50 OR brand = 'Apple';</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>AND - обидві умови мають бути правдиві. OR - хоча б одна з умов має бути правдивою.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Tab 2: JOIN Operations --> | |
| <section id="joins" class="tab-content"> | |
| <h2>JOIN - Об'єднання таблиць</h2> | |
| <div class="commands-grid"> | |
| <!-- INNER JOIN --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">INNER JOIN</code> | |
| <span class="badge join">Join</span> | |
| </div> | |
| <p class="description">Перетин даних з двох таблиць</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT users.name, orders.total | |
| FROM users | |
| INNER JOIN orders ON users.id = orders.user_id;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Показує тільки записи, які є в обох таблицях. Якщо користувача немає в orders, його не буде в результаті.</p> | |
| </div> | |
| </div> | |
| <!-- LEFT JOIN --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">LEFT JOIN</code> | |
| <span class="badge join">Join</span> | |
| </div> | |
| <p class="description">Всі записи з лівої таблиці</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT users.name, orders.total | |
| FROM users | |
| LEFT JOIN orders ON users.id = orders.user_id;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Показує всіх користувачів, навіть тих, які не мають замовлень. Для них orders.total буде NULL.</p> | |
| </div> | |
| </div> | |
| <!-- RIGHT JOIN --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">RIGHT JOIN</code> | |
| <span class="badge join">Join</span> | |
| </div> | |
| <p class="description">Всі записи з правої таблиці</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT users.name, orders.total | |
| FROM users | |
| RIGHT JOIN orders ON users.id = orders.user_id;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Протилежність LEFT JOIN. Показує всі замовлення, навіть якщо користувача немає.</p> | |
| </div> | |
| </div> | |
| <!-- FULL JOIN --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">FULL JOIN</code> | |
| <span class="badge join">Join</span> | |
| </div> | |
| <p class="description">Всі записи з обох таблиць</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT users.name, orders.total | |
| FROM users | |
| FULL JOIN orders ON users.id = orders.user_id;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Комбінує LEFT та RIGHT JOIN. Показує всі користувачи та всі замовлення. Деякі поля можуть бути NULL.</p> | |
| </div> | |
| </div> | |
| <!-- Multiple JOINs --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">Multiple JOINs</code> | |
| <span class="badge join">Join</span> | |
| </div> | |
| <p class="description">Об'єднання 3+ таблиць</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>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;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Об'єднує кілька таблиць разом. Кожен JOIN додає нову таблицю та умову з'єднання.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Tab 3: Aggregation --> | |
| <section id="aggregation" class="tab-content"> | |
| <h2>Агрегуючі функції</h2> | |
| <div class="commands-grid"> | |
| <!-- COUNT --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">COUNT()</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Підрахунок кількості записів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT COUNT(*) FROM users; | |
| SELECT COUNT(DISTINCT country) FROM users;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Першим запитом рахує всіх користувачів. Другим - кількість унікальних країн.</p> | |
| </div> | |
| </div> | |
| <!-- SUM --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">SUM()</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Сума значень</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT SUM(total) FROM orders; | |
| SELECT SUM(price * quantity) FROM cart_items;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Додає всі значення колонки. Приклад: загальна сума всіх замовлень.</p> | |
| </div> | |
| </div> | |
| <!-- AVG --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">AVG()</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Середнє значення</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT AVG(price) FROM products; | |
| SELECT AVG(age) FROM users WHERE country = 'Ukraine';</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Розраховує середнє значення. Приклад: середня ціна товару чи середній вік.</p> | |
| </div> | |
| </div> | |
| <!-- MAX / MIN --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">MAX() / MIN()</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Максимальне та мінімальне значення</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT MAX(price) FROM products; | |
| SELECT MIN(age) FROM users; | |
| SELECT MAX(salary), MIN(salary) FROM employees;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>MAX - найбільше значення, MIN - найменше значення. Приклад: найдорожчий та найдешевший товар.</p> | |
| </div> | |
| </div> | |
| <!-- GROUP BY --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">GROUP BY</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Групування результатів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT country, COUNT(*) as user_count | |
| FROM users | |
| GROUP BY country; | |
| SELECT category, AVG(price) as avg_price | |
| FROM products | |
| GROUP BY category;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Групує дані за вказаною колонкою, потім застосовує агрегуючу функцію до кожної групи.</p> | |
| </div> | |
| </div> | |
| <!-- HAVING --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">HAVING</code> | |
| <span class="badge aggr">Aggregation</span> | |
| </div> | |
| <p class="description">Фільтрація групованих результатів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>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;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>WHERE працює на отримані дані, HAVING - на результати GROUP BY. Фільтрує групи за умовою.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Tab 4: Advanced --> | |
| <section id="advanced" class="tab-content"> | |
| <h2>Середні SQL команди</h2> | |
| <div class="commands-grid"> | |
| <!-- UNION --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">UNION</code> | |
| <span class="badge adv">Advanced</span> | |
| </div> | |
| <p class="description">Об'єднання результатів двох запитів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT name FROM customers | |
| UNION | |
| SELECT name FROM employees; | |
| SELECT email FROM users | |
| UNION ALL | |
| SELECT email FROM admins;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>UNION видаляє дублікати, UNION ALL залишає всі. Корисно для об'єднання даних з різних таблиць.</p> | |
| </div> | |
| </div> | |
| <!-- Subquery --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">Subquery</code> | |
| <span class="badge adv">Advanced</span> | |
| </div> | |
| <p class="description">Запит всередину запиту</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>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);</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Вкладений запит розраховується спочатку, потім його результат використовується у зовнішньому запиті.</p> | |
| </div> | |
| </div> | |
| <!-- CASE --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">CASE WHEN</code> | |
| <span class="badge adv">Advanced</span> | |
| </div> | |
| <p class="description">Умовна логіка в запиті</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>SELECT name, | |
| CASE | |
| WHEN age < 18 THEN 'Minor' | |
| WHEN age < 65 THEN 'Adult' | |
| ELSE 'Senior' | |
| END as age_group | |
| FROM users;</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>IF-THEN-ELSE логіка в SQL. Дозволяє створювати нові колонки на основі умов.</p> | |
| </div> | |
| </div> | |
| <!-- INSERT --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">INSERT</code> | |
| <span class="badge adv">Advanced</span> | |
| </div> | |
| <p class="description">Додавання нових записів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>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');</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Додає новий рядок у таблицю. Можна додати один або кілька записів одразу.</p> | |
| </div> | |
| </div> | |
| <!-- UPDATE --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">UPDATE</code> | |
| <span class="badge adv">Advanced</span> | |
| </div> | |
| <p class="description">Оновлення існуючих даних</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>UPDATE users SET age = 30 WHERE id = 5; | |
| UPDATE products SET price = price * 1.1 | |
| WHERE category = 'Electronics';</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Змінює дані в існуючих записах. БЕЗ WHERE буде оновлено ВСІ записи!</p> | |
| </div> | |
| </div> | |
| <!-- DELETE --> | |
| <div class="command-card"> | |
| <div class="command-header"> | |
| <code class="command-name">DELETE</code> | |
| <span class="badge danger">Danger</span> | |
| </div> | |
| <p class="description">Видалення записів</p> | |
| <div class="usage"> | |
| <strong>Як використовувати:</strong> | |
| <pre><code>DELETE FROM users WHERE id = 5; | |
| DELETE FROM logs WHERE created_at < '2020-01-01';</code></pre> | |
| </div> | |
| <div class="explanation"> | |
| <strong>Що робить:</strong> | |
| <p>Видаляє записи з таблиці. БЕЗ WHERE видалить ВСІ записи! Завжди перевіряйте запит!</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Tab 5: Examples --> | |
| <section id="examples" class="tab-content"> | |
| <h2>Практичні приклади</h2> | |
| <div class="example-cards"> | |
| <div class="example-card"> | |
| <h3>📊 Приклад 1: Статистика по країнам</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Кількість користувачів старше 18 років по країнам, їхній середній вік та найстарший користувач. Тільки країни з 5+ користувачами.</p> | |
| </div> | |
| <div class="example-card"> | |
| <h3>💰 Приклад 2: Топ товарів за продажами</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Топ 10 товарів за кількістю проданих одиниць. Тільки товари з продажами > 10.</p> | |
| </div> | |
| <div class="example-card"> | |
| <h3>👥 Приклад 3: Активні користувачи</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Активні користувачи з замовленнями та статистика по їхніх покупках.</p> | |
| </div> | |
| <div class="example-card"> | |
| <h3>🔍 Приклад 4: Користувачи без замовлень</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Користувачи, які ніколи не зробили жодного замовлення.</p> | |
| </div> | |
| <div class="example-card"> | |
| <h3>📈 Приклад 5: Порівняння з максимальною ціною</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Товари з різницею їхної ціни від максимальної.</p> | |
| </div> | |
| <div class="example-card"> | |
| <h3>🎯 Приклад 6: Категоризація за ціною</h3> | |
| <pre><code>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;</code></pre> | |
| <p><strong>Що показує:</strong> Товари розділені на ціневі сегменти за CASE WHEN.</p> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="footer"> | |
| <p>💚 SQL для новачків | Вивчайте з задоволенням</p> | |
| </footer> | |
| </div> | |
| <script src="script-sql.js"></script> | |
| </body> | |
| </html> | |