SQL: Реляционные базы данных – Telegram
SQL: Реляционные базы данных
1.02K subscribers
85 photos
1 video
56 links
Канал айтишника о реляционных базах данных, SQL и модели данных. У нас тут много, очень много практических разборов))

Меня зовут Владимир Лунев (@lejnlune). Интересуюсь архитектурой систем и моделей данных.
Download Telegram
🗑 Удаление данных в SQL: основы DELETE

Удаление данных — важная часть работы с БД. В SQL для этого используется оператор DELETE, который позволяет удалять конкретные строки в таблице.

Разберем основные типы манипуляций по удалению с исходной таблицей employees (таблица в картинке поста)

1️⃣ Удаление всех строк
DELETE FROM employees;

✔️ Удаляет все записи из таблицы.
🔹 Важно! Структура таблицы остается, но без данных.

2️⃣ Удаление с условием (WHERE)
DELETE FROM employees WHERE position = 'Analyst';

✔️ Удаляет только тех сотрудников, у кого position = 'Analyst'.
После выполнения запроса строка 3 исходной таблицы (картинка в посте) исчезнет.

3️⃣ Удаление с подзапросом. Пост про вложенные запросы тут
DELETE FROM employees
WHERE id IN (SELECT id FROM employees WHERE salary < 55000);

✔️Удаляет всех, у кого зарплата меньше 55 000.
🔹 IN (SELECT ...) находит id подходящих строк перед удалением.

4️⃣ Удаление без удаления структуры
DELETE не сбрасывает автоинкремент (AUTO_INCREMENT).
✔️ Если после DELETE добавить новую запись, её id не начнётся с 1, а продолжит счёт.

Если нужно сбросить счётчик, используй:
ALTER TABLE employees AUTO_INCREMENT = 1;

⚠️ Нужно учесть, что это изменит Id и других записей


⚠️ Когда использовать DELETE?
Удаление отдельных строк по условию.
Удаление с учетом зависимостей (FOREIGN KEY). Пост про внешние ключи тут
Удаление с возможностью отката (ROLLBACK).
Не использовать для полной очистки таблицы! Для этого есть TRUNCATE, но он относится к DDL и не поддерживает откат.

💡Курс от автора канала на Stepik с сертификатом
"DDL в SQL: Определение и управление структурами баз данных"
При переходе по данной ссылке скидка 50%

#Операторы_и_работа_с_данными
#SQL #DELETE #DML
👍9🔥3🌚3
🔥10 ОШИБОК В SQL, КОТОРЫЕ ДОРОГО СТОЯТ

При работе с базами данных всегда нужно помнить, что даже одна ошибка может привести к потере данных, неожиданным багам и замедлению работы БД.
Разбираем опасные ошибки и как их избежать!

1️⃣ Удаление без WHERE

Ошибка: Удаляет все строки в таблице, если не указать WHERE.
DELETE FROM orders;

✔️ Правильный вариант: Добавляем WHERE, чтобы удалить только нужные данные.
DELETE FROM orders WHERE status = 'canceled';

✔️ Если хочешь удалить всё, но сохранить структуру, лучше использовать TRUNCATE (но это уже DDL, а не DML).
TRUNCATE TABLE orders; -- Очищает таблицу мгновенно


2️⃣ Обновление без WHERE

Ошибка: Обновляет все строки в таблице, даже если это не требуется.
UPDATE employees SET salary = salary * 1.1;

✔️ Правильный вариант: Используем WHERE, чтобы обновить только нужные записи.
UPDATE employees SET salary = salary * 1.1 WHERE department = 'IT';


3️⃣ Дублирование данных при INSERT

Ошибка: Если запись с таким id уже есть, получим ошибку.
INSERT INTO users (id, name) VALUES (1, 'Alice');

✔️ Правильный вариант: Если id = 1 уже существует, обновляем запись.
INSERT INTO users (id, name) VALUES (1, 'Alice')
ON DUPLICATE KEY UPDATE name = 'Alice'; -- MySQL

✔️ В PostgreSQL аналог:
INSERT INTO users (id, name) VALUES (1, 'Alice')
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name;


4️⃣ Пропуск ROLLBACK в транзакциях

Ошибка: Если не выполнить ROLLBACK, транзакция зависнет, а данные останутся заблокированными.
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- Ошибка в коде, транзакция зависла

✔️ Правильный вариант: Закрываем транзакцию COMMIT или ROLLBACK.
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT; -- Фиксируем изменения
-- Если что-то пошло не так:
ROLLBACK; -- Отменяем изменения


5️⃣ Невнимательность к NULL

Ошибка: NULL не участвует в сравнении, поэтому часть данных теряется.
SELECT * FROM users WHERE age > 30;

✔️ Правильный вариант: Добавляем OR age IS NULL, если NULL допустим.
SELECT * FROM users WHERE age > 30 OR age IS NULL;


6️⃣ Забытые RETURNING в DELETE и UPDATE (PostgreSQL, Oracle)

Ошибка: Мы удалили или обновили данные, но не знаем какие именно.
DELETE FROM orders WHERE status = 'canceled';

✔️ Правильный вариант: Используем RETURNING, чтобы получить удалённые записи.
DELETE FROM orders WHERE status = 'canceled' RETURNING *;


7️⃣ Использование DELETE вместо TRUNCATE для очистки таблицы

Ошибка: DELETE удаляет строки по одной, что медленно на больших объёмах.
DELETE FROM logs;

✔️ Лучший вариант (но это уже DDL):
TRUNCATE TABLE logs;  -- Очищает таблицу быстрее

✔️ В DML можно использовать DELETE с RETURNING, если важен список удалённых данных.
DELETE FROM logs RETURNING COUNT(*);


8️⃣ Неиспользование LIMIT при массовых изменениях

Ошибка: Этот запрос может удалить миллионы строк и создать нагрузку.
DELETE FROM sessions WHERE created_at < NOW() - INTERVAL '30 days';

✔️ Лучший вариант: Удаляем порциями, если данных много.
DELETE FROM sessions WHERE created_at < NOW() - INTERVAL '30 days' LIMIT 1000;


📌 Сохрани, чтобы не допустить эти ошибки!

💡Курс от автора канала на Stepik с сертификатом
"DDL в SQL: Определение и управление структурами баз данных"
При переходе по данной ссылке скидка 50%

#Операторы_и_работа_с_данными
#SQL #Оптимизация_SQL #Ошибки_SQL
👍6🔥4🌚3
🔥 Необычные SQL-команды, о которых знают не все!

SQL — это не только SELECT, INSERT, UPDATE и DELETE. Есть малоизвестные, но полезные команды, которые могут упростить жизнь. Разберём 4 необычные команды с примерами!

1️⃣ COALESCE — замена NULL на значение по умолчанию
Иногда в данных встречается NULL, который ломает вычисления. COALESCE помогает заменить NULL на значение по умолчанию.

Пример:
SELECT name, COALESCE(salary, 50000) AS salary  
FROM employees;

🔹 Почему? Если salary равно NULL, вместо него подставится 50000.

2️⃣ INSERT IGNORE — вставка без ошибок
Если пытаетесь вставить строку, но она нарушает ограничения (например, уникальный ключ), стандартный INSERT выдаст ошибку. INSERT IGNORE просто пропустит конфликтную запись.

Пример:
INSERT IGNORE INTO users (id, name)  
VALUES (1, 'Иван');

🔹 Почему? Если запись с id = 1 уже есть, ошибка не произойдёт.

3️⃣ REGEXP — поиск по шаблону (MySQL, PostgreSQL)
Когда LIKE не справляется, можно использовать REGEXP для гибкого поиска по регулярным выражениям.

Пример:
SELECT * FROM users  
WHERE name REGEXP '^Андрей|^Алексей';

🔹 Почему? Найдёт всех, чьё имя начинается с «Андрей» или «Алексей».

4️⃣ LATERAL — динамические подзапросы (PostgreSQL, Oracle)
Позволяет передавать данные из одного запроса в другой внутри JOIN.

Пример:
SELECT u.name, o.order_date  
FROM users u
JOIN LATERAL (SELECT * FROM orders WHERE orders.user_id = u.id LIMIT 1) o ON true;

🔹 Почему? Покажет только один последний заказ для каждого пользователя.

📌 Вывод:
⚡️ COALESCE спасает от NULL
⚡️ INSERT IGNORE предотвращает ошибки вставки
⚡️ REGEXP расширяет возможности поиска
⚡️ LATERAL даёт гибкость подзапросам

💡 Знал ли ты о всех этих командах? Делись в комментариях!

💡Курс от автора канала на Stepik с сертификатом
"DDL в SQL: Определение и управление структурами баз данных"
При переходе по данной ссылке скидка 50%

#Операторы_и_работа_с_данными
#SQL #DML
👍7🔥6💯4
🔥 7 ОШИБОК В SQL, КОТОРЫЕ МОГУТ СТОИТЬ КАРЬЕРЫ

SQL — это не просто язык запросов, а мощный инструмент управления данными. Но если им пользоваться неправильно, база может тормозить, данные потеряются, а коллеги будут недовольны. Разберем частые ошибки.

1️⃣ Использовать SELECT * в продакшене
⚠️ Почему это плохо?
🔹 Забирает всю таблицу, даже если нужны 2-3 колонки
🔹 Ломает код при изменении структуры таблицы
🔹 Усложняет работу оптимизатора запросов

Как правильно?
Выбираем только нужные столбцы:
SELECT id, name, salary FROM employees;

Если нужно получить все столбцы динамически — лучше заранее уточнить их в коде приложения.
Гайд по команде тут

2️⃣ Игнорировать индексы на больших таблицах
⚠️ Почему это плохо?
🔹 Запросы без индексов работают в десятки раз медленнее
🔹 БД вынуждена сканировать всю таблицу
🔹 Производительность падает на глазах

Как правильно?
Добавляем индекс на часто используемые столбцы (например, при фильтрации по salary):
CREATE INDEX idx_salary ON employees(salary);

💡 Но не переусердствуй! Лишние индексы замедляют INSERT и UPDATE.
Пост про индексы тут

3️⃣ Хранить пароли в открытом виде
⚠️ Почему это плохо?
🔹Любая утечка данных = утечка всех паролей пользователей
🔹 Это критическая уязвимость

Как правильно?
Пароли всегда хэшируются перед сохранением. Никогда не храни их в открытом виде!
INSERT INTO users (username, password)  
VALUES ('admin', SHA2('mysecretpass', 256));

💡 Лучше использовать bcrypt или argon2, так как они более надёжны, чем SHA2.

4️⃣ Забывать про транзакции при изменении данных
⚠️ Почему это плохо?
🔹 Если процесс прервётся, часть данных может остаться несохранённой
🔹 Без ROLLBACK нельзя откатить ошибочные изменения

Как правильно?
Используем транзакции при изменении нескольких таблиц сразу:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

💡 Если что-то пошло не так, можно откатить изменения:
ROLLBACK;

Всегда используй COMMIT только тогда, когда уверен, что всё прошло успешно!

5️⃣ Запускать тяжёлые запросы без EXPLAIN
⚠️ Почему это плохо?
🔹 Запрос может внезапно зависнуть на часы
🔹 Может заблокировать всю базу для других пользователей

Как правильно?
Перед выполнением сложного запроса проверяем его план выполнения:
EXPLAIN ANALYZE SELECT * FROM orders WHERE total > 10000;


💡 Что важно проверить?
🔹Есть ли Table Scan (это плохо, нужен индекс)
🔹Использует ли SQL ключи и индексы
🔹Какое количество строк реально обрабатывается

6️⃣ Забывать LIMIT при DELETE и UPDATE
⚠️ Почему это плохо?
🔹Если случайно забыть WHERE, можно удалить ВСЕ данные 😱
🔹Один неверный UPDATE может затронуть миллионы строк

Как правильно?
Ограничиваем DELETE и UPDATE, чтобы не изменить слишком много строк:
Пример с лимитами для DELETE:
DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY LIMIT 1000;

Пример с лимитами для UPDATE:
UPDATE employees SET salary = salary * 1.1 WHERE department = 'IT' LIMIT 500;

💡 В PostgreSQL LIMIT в UPDATE и DELETE не работает. Используй WHERE id IN (SELECT id FROM table LIMIT X).

7️⃣ Злоупотреблять NULL в таблицах
⚠️ Почему это плохо?
🔹NULL ломает агрегатные функции (SUM, AVG)
🔹NULL усложняет условия в JOIN и WHERE
🔹Фильтрация NULL требует специальных проверок (IS NULL, а не =)

Как правильно?
Если NULL можно избежать, используй значения по умолчанию:
ALTER TABLE users ALTER COLUMN email SET DEFAULT 'не указан';

💡 Если NULL неизбежен (например, у поля middle_name), всегда пиши COALESCE, чтобы избежать сюрпризов:
SELECT COALESCE(middle_name, '—') FROM users;

Подробнее про COALESCE тут

🔥 Вывод:
Эти ошибки встречаются даже у опытных разработчиков. Теперь ты знаешь, как их избежать!

💬 Какие ошибки ты встречал чаще всего? Пиши в комментариях!

💡Курс от автора канала на Stepik с сертификатом
"DDL в SQL: Определение и управление структурами баз данных"
При переходе по данной ссылке скидка 50%

#Операторы_и_работа_с_данными
#SQL #Оптимизация_SQL #Ошибки_SQL
🔥9👍5💯4
🗄 Типы данных в SQL: основы

Типы данных – это фундаментальная часть SQL, влияющая на DML (манипуляции данными) и DDL (структура базы). Они определяют, как хранятся, обрабатываются и извлекаются данные, а неправильный выбор может привести к проблемам с производительностью, точностью и хранением. Тип данных задается при создании таблиц.

1️⃣ Числовые типы
SQL поддерживает два основных вида чисел: целые и дробные.
✔️Целые (INTEGER, SMALLINT, BIGINT) — подходят для хранения чисел без дробной части, например, идентификаторов или количественных данных.
✔️Дробные (DECIMAL, NUMERIC, FLOAT, REAL) — используются для финансовых расчётов и значений с плавающей точкой.
⚠️Важно! FLOAT и REAL могут терять точность из-за особенностей работы с плавающей точкой. Для финансовых операций лучше использовать DECIMAL.

2️⃣ Строковые типы
Строки хранят текстовую информацию, но выбор неправильного типа может повлиять на эффективность.
✔️CHAR(N) — фиксированная длина строки, используется, если длина всегда одинаковая (например, коды стран).
✔️VARCHAR(N) — переменная длина, подходит для большинства текстовых данных.
✔️TEXT или CLOB — для хранения больших текстов (например, описаний или комментариев).
⚠️Важно! TEXT не индексируется напрямую в большинстве СУБД, поэтому его лучше использовать для больших объемов данных, но не для поиска.

3️⃣ Даты и время
Работа со временем в SQL требует понимания разных типов:
✔️DATE — хранит только дату (год, месяц, день).
✔️TIME — хранит только время (часы, минуты, секунды).
✔️TIMESTAMP — объединяет дату и время, может учитывать часовой пояс.
📌 Совет! Для работы с временными зонами, особенно если система поддерживает пользователей из разных регионов, лучше использовать TIMESTAMP WITH TIME ZONE, если это поддерживается в вашей СУБД.

4️⃣ Хранение сложных данных
Современные базы данных позволяют хранить не только числа и строки:
✔️JSON — полезен для структурированных данных, например, в PostgreSQL (jsonb) и MySQL.
✔️XML — используется в корпоративных системах, где требуется строгая структура данных.
📌 Совет! Если часто требуется поиск по JSON, лучше выбирать jsonb в PostgreSQL, так как он индексируется.

Пример создания таблицы с разными типами данных (помним, что создание таблиц в БД это подъязык SQL - DDL)
CREATE TABLE products (
product_id INTEGER PRIMARY KEY, -- Целочисленный идентификатор товара
name VARCHAR(255), -- Название товара, переменная строка
denoscription TEXT, -- Описание товара, длинный текст
price DECIMAL(10,2), -- Цена товара с двумя знаками после запятой
stock_quantity SMALLINT, -- Количество товара в наличии, небольшое целое число
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Дата и время создания записи
updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- Дата и время последнего обновления
is_active BOOLEAN DEFAULT TRUE, -- Флаг активности товара (true/false)
metadata JSON -- Дополнительные данные в JSON-формате (если поддерживается СУБД)
);


Разбор типов данных из примера:
✔️ INTEGER — идентификатор, удобен для автоинкремента.
✔️ VARCHAR(255) — хранит строки переменной длины, используется для наименований.
✔️ TEXT — предназначен для больших текстов (например, описание товаров).
✔️ DECIMAL(10,2) — важен для хранения денежных значений, исключает ошибки округления.
✔️ SMALLINT — экономит место, если числовые значения небольшие.
✔️ TIMESTAMP — фиксирует дату и время, можно использовать для аудита изменений.
✔️ BOOLEAN — хранит логические значения, удобен для активных/неактивных элементов.
✔️ JSON — подходит для хранения неструктурированных данных (например, дополнительных характеристик товара).

🔥 Вывод:
Выбор типа данных влияет на размер базы, скорость запросов и корректность вычислений. Ошибки могут привести к избыточному хранению, потерям точности и проблемам с производительностью.

#Операторы_и_работа_с_данными #SQL #Типы_данных
🔥10👍4💯4
💾 Реляционная модель данных: теория и принципы

Реляционная модель данных – это способ организации и представления данных в виде таблиц (или отношений). Она была предложена Эдгаром Ф. Коддом в 1970 году и стала основой для большинства современных систем управления базами данных (СУБД), таких как MySQL, PostgreSQL, Oracle, SQL Server.

В реляционной модели данные хранятся в виде таблиц (relations), а каждая строка в таблице представляет собой запись (tuple), содержащую значения атрибутов (столбцов).

💾 Основные компоненты реляционной модели:

1️⃣ Отношение (Relation) = Таблица.
Основная структура хранения данных.
Состоит из строк (кортежей) и столбцов (атрибутов).

2️⃣ Атрибут (Attribute) = Столбец таблицы.
Определяет характеристику сущности (например, «Имя», «Цена», «Дата»).
Каждый атрибут имеет свой тип данных (INTEGER, VARCHAR, DATE и т. д.).

3️⃣ Кортеж (Tuple) = Строка в таблице.
Представляет собой один экземпляр сущности (например, одну запись о клиенте).

4️⃣ Домен (Domain) = Диапазон допустимых значений для атрибута.
Например, для атрибута «Возраст» допустимы только целые числа от 0 до 120.

5️⃣ Первичный ключ (Primary Key, PK)
Уникальный идентификатор строки в таблице (например, ID клиента).

6️⃣ Внешний ключ (Foreign Key, FK)
Ссылка на первичный ключ другой таблицы, создающая связь между таблицами.

💾 Принципы реляционной модели

1️⃣ Единообразное представление данных.
Все данные хранятся в виде таблиц, каждая из которых представляет сущность.

2️⃣ Уникальность строк.
Каждая строка (запись) в таблице должна быть уникальной и идентифицироваться первичным ключом.

3️⃣ Отсутствие повторяющихся данных (нормализация).
Повторяющиеся данные должны минимизироваться путём разбиения на связанные таблицы.

4️⃣ Целостность данных.
1. Сущностная целостность – каждый кортеж должен иметь уникальный первичный ключ.
2. Ссылочная целостность – внешний ключ должен ссылаться на существующую запись.
3. Доменная целостность – данные должны соответствовать определённому типу.

5️⃣ Манипуляции с данными через SQL.
Язык SQL используется для выполнения операций над таблицами и управления БД (SELECT, INSERT, UPDATE, DELETE и прочее).

💾 Связи между таблицами
Реляционная модель позволяет строить связи между таблицами:

1️⃣ Один ко многим (1:M)
1. Например, один клиент может иметь несколько заказов.
2. Внешний ключ в таблице заказов ссылается на первичный ключ клиента.

2️⃣ Многие ко многим (M:N)
1. Например, один студент может записаться на несколько курсов, и каждый курс может включать многих студентов.
2. Решается через промежуточную таблицу.

3️⃣ Один к одному (1:1)
Например, один сотрудник может иметь один личный кабинет.

🔹 Преимущества реляционной модели
Гибкость – легко изменять и расширять структуру базы.
Целостность – строгие ограничения предотвращают ошибки и дублирование данных.
Эффективность запросов – возможность использования индексов, оптимизации SQL-запросов.
Универсальность – подходит для большинства бизнес-приложений.

🔹 Недостатки реляционной модели
Производительность на больших объёмах данных – при очень больших данных (миллиарды записей) NoSQL-решения могут быть быстрее.
Сложность масштабирования – горизонтальное масштабирование сложнее, чем в NoSQL.
Жёсткость схемы – структура таблиц фиксирована, что требует продуманного проектирования.

🔥 Вывод
Реляционная модель данных остаётся основным стандартом хранения структурированной информации. Она обеспечивает надёжность, удобство работы и точность данных. Однако, для больших распределённых систем могут использоваться альтернативные модели, такие как NoSQL (документные, графовые, колонночные базы).

💡Курс от автора канала на Stepik с сертификатом
"DDL в SQL: Определение и управление структурами баз данных"
При переходе по данной ссылке скидка 50%

#Реляционные_базы_данных #SQL
🔥11👍5💯4👾1
🔍 Функция CASE – условные конструкции в SQL

Функция CASE работает аналогично if-else в языках программирования. Она позволяет проверять условия и возвращать разные значения в зависимости от их выполнения.

Как работает?
SQL проверяет условия WHEN сверху вниз. Как только условие выполнено, возвращается соответствующее значение THEN. Если ни одно из условий не выполнено, используется ELSE (если он указан).

Пример:
Классифицируем сотрудников по уровню зарплаты.

Допустим, у нас есть следующая таблица employees:
name          salary
Иван 6000
Ольга 4500
Алексей 3000
Мария 2000


Подготовим запрос для классификации:
SELECT name, 
salary,
CASE
WHEN salary > 5000 THEN 'Высокая зарплата'
WHEN salary BETWEEN 3000 AND 5000 THEN 'Средняя зарплата'
ELSE 'Низкая зарплата'
END AS salary_category
FROM employees;


Логически функция CASE из данного запроса выглядит так:
CASE 
WHEN -- условие 1
WHEN -- условие 2
ELSE -- иначе, если не соблюдены условия
END AS -- пользовательское название столбца для записи результатов


После выполнения запроса база данных вернёт следующий результат:
name        salary    salary_category
Иван 6000 Высокая зарплата
Ольга 4500 Средняя зарплата
Алексей 3000 Средняя зарплата
Мария 2000 Низкая зарплата


Что происходит?
WHEN 1 - если salary больше 5000 – в столбец salary_category записывается 'Высокая зарплата'
WHEN 2 - если salary от 3000 до 5000 – записывается 'Средняя зарплата'
ELSE - если ни одно из условий не выполнено – записывается 'Низкая зарплата'

Где полезно?
✔️Создание категорий (например, разделение клиентов по уровню покупок).
✔️Генерация текстовых описаний на основе данных.
✔️Гибкая обработка данных прямо в SQL-запросе без изменения исходной таблицы.

#Операторы_и_работа_с_данными #CASE

Подписаться на канал
🔥11💯3👾3
Какой результат вернёт следующий запрос, если salary = 3500? (теория в посте выше)

SELECT CASE  
WHEN salary > 5000 THEN 'Высокая зарплата'
WHEN salary BETWEEN 3000 AND 5000 THEN 'Средняя зарплата'
ELSE 'Низкая зарплата'
END AS salary_category;


#тест
👾6🔥3
Выберите вариант ответа на тестовое задание:
Anonymous Quiz
15%
Высокая зарплата
79%
Средняя зарплата
6%
Низкая зарплата
🔥5🤔3🌚3🤯1👾1
🔍 Основы COALESCE — защита от NULL в SQL

В SQL часто встречаются ситуации, когда в данных есть NULL — отсутствие значения. Это может вызвать ошибки или неожиданные результаты при обработке данных. Функция COALESCE() решает эту проблему, подставляя первое ненулевое значение из списка.

🛠 Синтаксис
COALESCE(значение1, значение2, ..., значениеN)

1. SQL проверяет аргументы слева направо и возвращает первое ненулевое значение.
2. Если все аргументы NULL, результат тоже будет NULL.

✔️ Пример 1: Подстановка значения по умолчанию
Допустим, у нас есть таблица users, где phone может быть NULL. Чтобы заменить NULL на строку 'Нет номера', используем COALESCE():
SELECT name, COALESCE(phone, 'Нет номера') AS phone_display
FROM users;

* Если в запросе вместо ненулевого последнего аргумента 'Нет номера' указать просто ' ', то в выгрузке запрос выведет NULL там, где номер телефона NULL в БД.

После выполнения запроса база данных вернет результат:
name    phone    phone_display
Иван +10101 +10101
Анна NULL Нет номера


Как это работает?
1. Если phone не NULL, вернётся его значение.
2. Если phone = NULL, подставится 'Нет номера' в столбец phone_display.

✔️ Пример 2: Выбор приоритета из нескольких колонок
Допустим, у нас есть несколько номеров телефона (work_phone, mobile_phone, home_phone). Нам нужно вывести первый доступный:
SELECT name, COALESCE(work_phone, mobile_phone, home_phone, 'Нет') AS preferred_phone
FROM users;


После выполнения запроса база данных вернет результат (сократил названия столбов, чтобы таблица корректно отображалась не с десктопа):
name  work_p mobile_p home_p pref_p
Иван NULL NULL 555-1 555-1
Анна 777-5 999-9 NULL 777-5
Олег NULL NULL NULL Нет


Как это работает?
1. SQL сначала проверяет значение work_phone: если оно не NULL, оно и выводится.
2. Если work_phone = NULL, проверяется mobile_phone.
3. Если оба предыдущих столбца NULL, берётся home_phone.
4. Если все три NULL, подставляется последний не нулевой аргумент функции – 'Нет номера' в итоговый столбец preferred_phone.

Где полезно?
✔️ Замена NULL на значения по умолчанию.
✔️ Упрощение логики выбора из нескольких колонок.
✔️ Предотвращение ошибок при работе с NULL.

#Операторы_и_работа_с_данными #COALESCE

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👾5🤔2
📊 Нормальные формы в реляционных базах данных: что это и зачем нужно?

При проектировании и пользовательской эксплуатации реляционной базы данных важно следовать нормальным формам (NF), чтобы избежать избыточности, аномалий обновления и повысить целостность данных. Давайте разберёмся, какие бывают нормальные формы и как они работают.

Нормальная форма в реляционной модели данных — это свойство отношения, характеризующее его с точки зрения избыточности, потенциально приводящей к логически ошибочным результатам выборки или изменения данных, чем меньше избыточность тем выше "нормальность данных"

Процесс преобразования отношений базы данных к виду, отвечающему нормальным формам, называется нормализацией. Нормализация предназначена для приведения структуры БД к виду, обеспечивающему минимальную логическую избыточность. Конечной целью нормализации является уменьшение потенциальной противоречивости хранимой в базе данных информации.

Разберем на примерах первые три вида нормальных форм являющихся фундаментом нормализации БД.

1️⃣ Первая нормальная форма (1NF)
Требование:
1. Все атрибуты содержат только атомарные значения (неделимые).
2. Нет повторяющихся групп (множественных значений в одной ячейке).

Плохо (не 1NF):
id  name  phones
1 Иван +123, +456, +789

✔️ Хорошо (1NF):
id   name   phone
1 Иван +123
1 Иван +456
1 Иван +789

Разделили атрибут phones на отдельные строки — теперь каждая ячейка содержит одно значение.

2️⃣ Вторая нормальная форма (2NF)
Требование:
1. Таблица уже в 1NF.
2. Все неключевые атрибуты зависят только от полного первичного ключа (если ключ составной).

Плохо (не 2NF):
student_id  course_id course_name
1 SQL101 Основы SQL
2 SQL101 Основы SQL

course_name зависит только от course_id, а не от полного составного ключа (student_id, course_id).

✔️ Хорошо (2NF):
Разбиваем таблицу на две таблицы содержащие логически единую информацию.

Таблица студентов и курсов:
student_id   course_id
1 SQL101
2 SQL101

Таблица курсов:
course_id        course_name
SQL101 Основы SQL

Теперь course_name зависит только от course_id, а не от полного ключа.

3️⃣ Третья нормальная форма (3NF)
Требование:
1. Таблица уже в 2NF.
2. Нет транзитивных зависимостей (атрибуты зависят только от первичного ключа, а не друг от друга).

Плохо (не 3NF):
employee_id   dep_id   dep_name
1 10 IT
2 20 HR

dep_name зависит от dep_id, а не от первичного ключа employee_id.

✔️ Хорошо (3NF):
Разделяем таблицы логически делящие информацию.

Таблица сотрудников:
employee_id   dep_id
1 10
2 20

Таблица отделов:
dep_id   dep_name
10 IT
20 HR

Теперь dep_name хранится отдельно и зависит только от dep_id.

💡Вывод
Нормализация помогает избежать дублирования данных, уменьшить избыточность и повысить целостность БД.
1NF — атомарные значения.
2NF — зависимость только от полного первичного ключа.
3NF — отсутствие транзитивных зависимостей.

#Реляционные_базы_данных #Оптимизация_SQL #Нормализация

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👾5💯4
📊 Продвинутые нормальные формы в реляционных базах данных

Если 1NF, 2NF и 3NF (разобрали в этом посте) помогают избежать дублирования данных и аномалий обновления, то 4NF, 5NF и 6NF направлены на устранение более сложных зависимостей и оптимизацию структуры данных.

Давайте разберёмся, зачем они нужны и когда их применять.

4️⃣ Четвёртая нормальная форма (4NF) — применяется для устранения многозначных зависимостей, где столбец с первичным ключом имеет связь «один-ко-многим» со столбцом, который не является ключом. Эта форма устраняет некорректные отношения «многие-ко-многим».
Требование:
1. Таблица уже в 3NF
2. Нет многозначных зависимостей

Плохо (не 4NF):
Представим, что один преподаватель может вести несколько предметов и работать в нескольких аудиториях.
teacher_id   subject      classroom
1 SQL 101
1 Python 101
1 SQL 102
1 Python 102

Преподаватель 1 ведёт несколько предметов и работает в нескольких аудиториях. Предмет и аудитория независимы, но при этом создают дублирование данных.

✔️ Хорошо (4NF):
Разбиваем таблицу на две:

Преподаватель — Предмет:
teacher_id   subject
1 SQL
1 Python

Преподаватель — Аудитория:
teacher_id   classroom
1 101
1 102

Теперь предмет и аудитория хранятся отдельно, убирая многозначную зависимость.

5️⃣ Пятая нормальная форма (5NF) — разделяет таблицы на более малые таблицы для устранения избыточности данных. Разбиение идёт до тех пор, пока нельзя будет воссоздать оригинальную таблицу путём объединения малых таблиц.
Требование:
1. Таблица уже в 4NF.
2. Нет соединительных (join) зависимостей — данные не должны разлагаться на более мелкие части без потери информации.

Плохо (не 5NF):
project_id  employee_id role
1 100 Разработчик
1 101 Тестировщик
2 100 Разработчик
2 102 Аналитик

Каждый проект связан с сотрудником и его ролью, но возможны дублирования.

✔️ Хорошо (5NF):
Разделяем на три таблицы

Проекты:
project_id
1
2

Сотрудники:
employee_id
100
101
102

Связь проектов и сотрудников через роли в новой стаблице:
project_id employee_id role
1 100 Разработчик
1 101 Тестировщик
2 100 Разработчик
2 102 Аналитик

Теперь данные связаны через таблицы без лишнего дублирования.

6️⃣ Шестая нормальная форма (6NF) — Каждое ограничение в связях между таблицами должно зависеть только от ключей и доменов, т.е допустимых значений столбцов. 6NF предотвращает недопустимые данные, устанавливая ограничения на уровне отношений, а не отдельных таблиц или столбцов.
Требование:
1. Таблица уже в 5NF.
2. Разделение на атомарные отношения (каждое изменение данных должно касаться только одной сущности).

Важно: 6NF встречается редко и полезна в хранилищах данных и системах, требующих историчности данных. По своему опыту скажу, что она скорее теоретическая и направлена на устранение всех возможных избыточностей.

Пример:
Допустим, нам нужно хранить историю изменения зарплаты сотрудников.
Плохо (не 6NF):
employee_id salary dep  date
1 5000 IT 2024-01-01
1 5500 IT 2024-03-01
1 5500 HR 2024-05-01

Изменение отдела ведёт к дублированию зарплаты, что может привести к несогласованности данных.

✔️Хорошо (6NF):
Разделяем данные на независимые отношения:

История зарплаты
employee_id salary   date
1 5000 2024-01-01
1 5500 2024-03-01

История департаментов
employee_id dep  date
1 IT 2024-01-01
1 HR 2024-05-01

Теперь изменения хранятся отдельно и позволяют вести историю без дублирования.

💡Вывод
Продвинутые нормальные формы помогают устранить избыточные зависимости и дублирование, улучшая целостность данных.
4NF – исключает многозначные зависимости.
5NF – убирает дубли через разбиение отношений.
6NF – делает данные полностью атомарными, что полезно для историчности.

#Реляционные_базы_данных #Оптимизация_SQL #Нормализация

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7💯4👾4
🛠 Базовые SQL-команды для уровня Junior

Джуниор в SQL – это начинающий специалист, который работает с базами данных и владеет основами языка SQL. Обычно он занимает позицию Junior Database Developer, Junior Data Analyst, Junior SQL Developer или Junior DBA (Database Administrator). Также знание SQL крайне актуально для системных аналитиков.

Если ты только начинаешь свой путь в SQL, вот основные команды, которые нужно знать!

1️⃣ SELECT – выбор данных. Гайд тут
Извлекает данные из таблицы.
SELECT name, age FROM users;
-- Выбирает столбцы name и age из таблицы users


2️⃣ INSERT – добавление данных. Подробнее тут
Добавляет новые строки в таблицу.
INSERT INTO users (name, age) VALUES ('Алексей', 25);
-- Вставляет строку с именем "Алексей" и возрастом 25 в таблицу users


3️⃣ UPDATE – обновление данных. Подробнее тут
Изменяет существующие данные.
UPDATE users SET age = 26 WHERE name = 'Алексей';
-- Обновляет возраст пользователя "Алексей" на 26


4️⃣ DELETE – удаление данных. За подробностями сюда
Удаляет строки из таблицы.
DELETE FROM users WHERE age < 18;
-- Удаляет всех пользователей младше 18 лет


5️⃣ WHERE – фильтрация данных. Подробнее тут
Используется для выборки данных по условиям.
SELECT * FROM users WHERE age > 20;
-- Выбирает всех пользователей старше 20 лет


6️⃣ ORDER BY – сортировка данных
Сортирует результаты запроса.
SELECT * FROM users ORDER BY age DESC;
-- Выбирает всех пользователей и сортирует их по возрасту по убыванию


7️⃣ GROUP BY – группировка данных. Разбирали тут
Объединяет строки с одинаковыми значениями в одну группу.
SELECT age, COUNT(*) FROM users GROUP BY age;
-- Считает, сколько пользователей каждого возраста


8️⃣ JOIN – объединение таблиц. Объяснял в этом посте
Позволяет соединять данные из нескольких таблиц.
SELECT users.name, orders.total 
FROM users
JOIN orders ON users.id = orders.user_id;
-- Выбирает имена пользователей и суммы их заказов


Освоив эти команды, ты сможешь работать с БД на базовом уровне. Таже рекомендую изучить следующие материалы размещенные на канале внешний ключ, первичный ключ, основы реляционной модели данных тут, типы данных.

#Карьера_SQL, #Основы_SQL

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
👾8🔥6🤯2
📊 ORDER BY — как управлять порядком строк в результатах запроса?

Когда ты выполняешь SELECT, порядок строк не гарантирован. База данных возвращает строки в произвольном порядке, зависящем от её внутренней реализации. Если тебе нужен определённый порядок — используется ORDER BY.

Что такое ORDER BY?

ORDER BY — это инструкция, которая упорядочивает строки результата по значениям одного или нескольких столбцов.
Без него результаты могут быть хаотичными — особенно в больших таблицах.

Ключевые особенности:

1️⃣ Порядок по умолчанию — ASC (по возрастанию)
От меньшего к большему: 0 → 1 → 2, A → B → C

2️⃣ DESC — обратный порядок (по убыванию)
От большего к меньшему: Z → Y → X, 1000 → 100 → 10

3️⃣ Сортировка по нескольким столбцам
Если значения в первом столбце равны — используется второй, и так далее.

4️⃣ Можно сортировать по выражениям, функциям и псевдонимам

5️⃣ Можно использовать номер столбца в списке SELECT
Хотя это не рекомендуется для читаемости, но часто встречается в старом коде.

Синтаксис:
SELECT столбец1, столбец2, ...
FROM таблица
ORDER BY столбец1 [ASC | DESC], столбец2 [ASC | DESC], ...;


Примеры:
-- 1. По возрасту по возрастанию
SELECT name, age FROM users ORDER BY age;

-- 2. По возрасту по убыванию
SELECT name, age FROM users ORDER BY age DESC;

-- 3. По городу, затем по возрасту
SELECT name, city, age FROM users ORDER BY city ASC, age DESC;

-- 4. По длине имени
SELECT name FROM users ORDER BY LENGTH(name);


Важно:
1. ORDER BY всегда идёт в конце запроса, перед LIMIT, OFFSET, FETCH.
2. Он не изменяет порядок в самой таблице — только в результате запроса.
3. Если ты не укажешь ORDER BY, то повторные запросы могут возвращать строки в разном порядке.

Зачем нужен ORDER BY на практике?
✔️ Построение отчетов (например, по дате)
✔️ Вывод самых новых или самых старых записей
✔️ Получение топ-N результатов (вместе с LIMIT)
✔️ Для пользователей — упорядоченный, понятный вывод
✔️ Для анализа и сравнения значений

#Операторы_и_работа_с_данными #ORDER_BY

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👾4💯3
📋 Тест: сортировка данных по нескольким столбцам

Условие:
У вас есть таблица products, которая хранит информацию о товарах в магазине. Вам нужно отсортировать товары сначала по цене в порядке убывания, а затем по названию в алфавитном порядке.

Таблица products:
id    name      price
1 Apple 30
2 Banana 20
3 Orange 60
4 Cherry 80
5 Grape 40

Теория по ORDER BY в этом посте

#тест
👾5🔥3🤔2
Выберите вариант ответа на тестовое задание
Anonymous Quiz
86%
ORDER BY price DESC, name ASC
9%
ORDER BY price ASC, name ASC
5%
ORDER BY name ASC, price DESC
🔥7👾4
🧭 Порядок выполнения SQL-запроса: не такой, как кажется на первый взгляд!

Многие уверены, что SQL исполняется сверху вниз, потому что мы так его пишем: SELECT, потом FROM, потом WHERE и так далее.

Но СУБД (система управления базами данных) читает и исполняет его иначе. Понимание этого является ключом к уверенной работе с SQL и написанию эффективных запросов. К слову этот вопрос является достаточно распространенным каверзным вопросом на собесах.

Реальный порядок выполнения SQL-запроса:

1️⃣ FROM – сначала выбирается таблица (или несколько, если есть JOIN).
На этом этапе данные подтягиваются из таблиц, применяются условия соединения (ON), создаются временные таблицы для дальнейших шагов.
2️⃣ WHERE – фильтруются строки на уровне «сырых» данных.
Удаляются строки, которые не соответствуют критериям. Этот шаг нельзя использовать с агрегатными функциями (вроде AVG, SUM) — они ещё не посчитаны.
3️⃣ GROUP BY – группировка строк по одному или нескольким столбцам.
На этом шаге создаются группы для последующего анализа: например, по отделам, категориям, датам.
4️⃣ HAVING – фильтрация уже сгруппированных данных.
Применяется после GROUP BY, работает с агрегатами. Например: показать только те отделы, где средняя зарплата выше определённого порога.
5️⃣ SELECT – выбираются нужные столбцы, считаются выражения и функции.
Только теперь в дело вступают агрегаты (AVG, COUNT, MAX) и алиасы (AS name). Здесь формируется окончательный «вид» результата.
6️⃣ DISTINCT (если есть) – удаляются дубликаты.
Работает после SELECT. Используется для уникальных значений, но может быть затратен по ресурсам.
7️⃣ ORDER BY – сортировка итогового набора данных.
Можно сортировать по столбцу, выражению или порядковому номеру из SELECT.
8️⃣ LIMIT / OFFSET / FETCH – ограничение количества строк.
Используется в пагинации, топ-результатах и тестировании.

Пример запроса:
SELECT department, AVG(salary)
FROM employees
WHERE status = 'active'
GROUP BY department
HAVING AVG(salary) > 5000
ORDER BY AVG(salary) DESC
LIMIT 3;


Что делает запрос по шагам (порядок обработки СУБД):
1️⃣ FROM employees — загружает всех сотрудников
2️⃣ WHERE status = 'active' — оставляет только активных
3️⃣ GROUP BY department — группирует по департаментам
4️⃣ HAVING AVG(salary) > 5000 — отбирает департаменты с хорошей средней
5️⃣ SELECT department, AVG(salary) — выбирает поля
6️⃣ ORDER BY AVG(salary) DESC — сортирует по средней зарплате
7️⃣ LIMIT 3 — берёт только 3 топовых департамента

Совет:
Если запрос работает не так, как ты ожидал — проверь его на соответствие реальному порядку выполнения. Это поможет найти ошибки и понять логику SQL на глубоком уровне.

#Реляционные_базы_данных #СУБД #Оптимизация_SQL

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👾4💯3
🏷 Псевдонимы в SQL: зачем нужны AS и как правильно их использовать?

В SQL псевдонимы (alias) — это временные имена, которые можно присвоит столбцам или таблицам прямо в запросе. Они не меняют структуру базы данных, но делают запросы понятнее, короче и логичнее.

🔧 Синтаксис:
SELECT выражение AS псевдоним
FROM таблица AS псевдоним;

Слово AS можно опустить — но явное лучше неявного.

Пример 1: псевдоним для столбца
SELECT name, salary * 1.15 AS adjusted_salary
FROM employees;

adjusted_salary — это новое имя для результата выражения salary * 1.15.

Пример 2: псевдонимы в соединениях таблиц
SELECT e.name, d.name AS department
FROM employees AS e
JOIN departments AS d ON e.dept_id = d.id;

Удобно, когда имена таблиц длинные, или когда в запросе участвуют несколько таблиц с одинаковыми именами столбцов.

Что происходит в этом запросе?
1. employees AS e — Мы даём псевдоним e таблице employees. Теперь к её столбцам можно обращаться коротко: e. name, e. dept_id.
2. departments AS d — Аналогично, таблице departments присваиваем алиас d.
3. e. name и d. name — Здесь мы явно указываем, откуда брать каждый name, чтобы избежать путаницы.
4. d. name AS department — Мы даём столбцу более говорящий псевдоним, в результате запроса он будет отображаться как department, а не просто name.

Зачем нужны псевдонимы?
✔️ Читабельность: особенно полезно в сложных выражениях и подзапросах.
✔️ Разрешение конфликтов: если в нескольких таблицах одинаковые названия столбцов.
✔️ Переименование данных в отчётах: чтобы результат выглядел понятнее пользователю.

⚠️ Важно помнить:
Псевдонимы столбцов нельзя использовать в WHERE, потому что WHERE выполняется до SELECT.
Зато можно использовать в ORDER BY и HAVING. Пост про очередность выполнения тут

Пример из практики: расчёт налога и итоговой зарплаты
Задача: рассчитать 13% налог с зарплаты и итоговую сумму к выплате, вывести имя сотрудника, оклад, налог и сумму "на руки".
SELECT 
name AS employee_name,
salary AS base_salary,
salary * 0.13 AS tax_amount,
salary * 0.87 AS net_salary
FROM employees;


📎 Что происходит:
employee_name — читаемое имя вместо name
base_salary — для акцента на том, что это до вычета
tax_amount — отдельный расчёт налога
net_salary — итоговая сумма после удержания налога

В данном случае псевдоним создаёт новые столбцы в результирующей выгрузке запроса — но не в самой таблице в базе данных. Если мы будем формировать отчет на основе этих данных, то разобраться в нем становится намного проще.

📘 Заключение:
Псевдонимы — это не просто «красивости», а важный инструмент в арсенале каждого, кто работает с SQL. Они делают код читаемым, поддерживаемым и профессиональным.

#Операторы_и_работа_с_данными #Alias #Оптимизация_SQL

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
👾9🔥4💯2
🔁 Что такое транзакция?

Транзакция — это логически связанная группа SQL-операций, которые выполняются как единое целое. Она либо выполняется полностью, либо откатывается полностью, если возникла ошибка.

Если посмотреть с точки зрения машинной философии механизм транзакции можно выразить принципом «всё или ничего»

Ключевые команды:
1. BEGIN / START TRANSACTION – начало транзакции
2. COMMIT – подтверждение изменений
3. ROLLBACK – откат всех изменений с начала транзакции

💡 Почему это важно?
Представь, что ты переводишь деньги между счетами:
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

Если после первого запроса произойдёт сбой, то деньги «пропадут».

А если всё это завернуть в транзакцию — либо оба запроса сработают, либо ни один:
START TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

COMMIT;

Если что-то пойдёт не так, можно сделать откат:
ROLLBACK;


Полезно знать:
Транзакции подчиняются принципам ACID:
1. Atomicity — атомарность
2. Consistency — согласованность
3. Isolation — изолированность
4. Durability — надёжность

Заключение
Транзакции — это не просто дополнительная опция. Это механизм, который:
1. Защищает данные от потерь и ошибок;
2. Позволяет писать надёжные и предсказуемые бизнес-логики;
3. Обеспечивает правильность даже в условиях высокой нагрузки.

Делись с командой — это основа безопасной работы с данными.

#Операторы_и_работа_с_данными #Транзакция #Оптимизация_SQL

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👾5
🔔 Триггеры в SQL: автоматические действия в базе данных

Что такое триггер?
Триггер (trigger) — это специальная программа внутри СУБД, которая автоматически выполняет определённый SQL-код при наступлении события в таблице. Иными словами, триггер — это реакция базы данных на изменение данных.

Какие события могут активировать триггер?
Триггеры можно настроить на 3 типа событий:
1. INSERT — Добавление новой строки
2. UPDATE — Изменение существующей строки
3. DELETE — Удаление строки

Когда срабатывает триггер?
Есть два режима срабатывания:
1. BEFORE — До того, как операция будет завершена
2. AFTER — После выполнения операции

Это позволяет:
С BEFORE — предотвратить нежелательные действия (например, отклонить запись с ошибкой).
С AFTER — реагировать на уже выполненные изменения (например, логировать, уведомлять, синхронизировать).

Зачем нужны триггеры?
Примеры использования:
1. Автоматический лог изменений: записывать, кто и когда внёс изменения.
2. Синхронизация таблиц: при удалении строки из одной таблицы, удалить её из другой.
3. Уведомления: запускать действия при изменении статуса заказа.
4. Бизнес-правила: блокировать операции, нарушающие правила компании.

🛠 Синтаксис (на примере MySQL):
CREATE TRIGGER имя_триггера
[BEFORE | AFTER] [INSERT | UPDATE | DELETE]
ON имя_таблицы
FOR EACH ROW
BEGIN
-- SQL-действия*
END;
FOR EACH ROW означает, что триггер сработает для каждой строки, к которой применимо событие.

* - Внутри BEGIN ... END пишем обычный SQL-код.

Пример 1: логируем добавление сотрудника
Допустим, у нас есть таблица employees и таблица logs для записей о событиях.
CREATE TRIGGER log_employee_insert
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO logs(message)
VALUES (CONCAT('Добавлен сотрудник: ', NEW.name));
END;

🔍 Объяснение:
AFTER INSERT — триггер сработает после добавления нового сотрудника.
NEW. name — обращение к значению поля name в новой строке (та, что только что вставлена).
Вставляется строка в таблицу logs.

Пример 2: предотвратить удаление важной записи
CREATE TRIGGER protect_admin_delete
BEFORE DELETE ON users
FOR EACH ROW
BEGIN
IF OLD.role = 'admin' THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Нельзя удалить администратора!';
END IF;
END;

🔍 Объяснение:
BEFORE DELETE — триггер срабатывает до удаления.
OLD. role — значение удаляемой строки.
Если роль admin, выбрасывается ошибка, и удаление не происходит.

Разница между NEW и OLD
В INSERT только NEW — новая строка
В DELETE только OLD — удаляемая строка
В UPDATE оба: OLD — старая, NEW — новая

⚠️ Важные замечания
1. Один триггер = одно событие + одно время (BEFORE/AFTER).
2. Если нужно реагировать на разные события, создавайте несколько триггеров.
3. Не стоит делать сложную логику внутри триггера — это замедлит работу.
4. Циклические триггеры (когда один вызывает другой) могут привести к ошибкам или зависанию — избегайте этого.

📚 Резюме
CREATE TRIGGER — создание триггера
BEFORE / AFTER — время срабатывания
INSERT, UPDATE, DELETE — тип события
NEW, OLD — доступ к значениям до/после
FOR EACH ROW — выполняется для каждой строки

📌 Сохрани этот пост как шпаргалку!
🔁 Делись с коллегами — триггеры полезны, но ими часто пренебрегают.

#Операторы_и_работа_с_данными #Trigger

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👾6💯3
🧬 INSERT через SELECT: массовый перенос данных

INSERT INTO ... SELECT — это оператор массовой вставки. Вместо ручного ввода значений через VALUES, мы берем данные из существующей таблицы (или нескольких) и вставляем их в другую таблицу.

Это — основа для:
1. Копирования данных между таблицами
2. Архивирования записей
3. Миграции и трансформации данных
5. Наполнения витрин и отчётов
6. Подготовки временных таблиц в ETL-процессах

Синтаксис:
INSERT INTO target_table (col1, col2)
SELECT col_a, col_b
FROM source_table
WHERE condition;

Это не просто копирование — можно фильтровать, преобразовывать и агрегировать данные прямо на лету.

⚙️ Как работает?
1. Сначала выполняется SELECT — он формирует временный набор данных.
2. Затем INSERT INTO вставляет эти данные в указанную таблицу.
3. Всё это работает как единая транзакция.

Важно: порядок и типы колонок должны совпадать или быть совместимыми.

🔒 Строгие правила:
1. Количество колонок в INSERT INTO и SELECT должно совпадать.
2. Типы данных должны быть совместимыми: нельзя вставить TEXT в INT.
3. Если в целевой таблице есть NOT NULL, UNIQUE, FOREIGN KEY или DEFAULT, они тоже применяются.
4. Если есть автоинкремент (AUTO_INCREMENT), значение можно не указывать, оно подставится само.

⚠️ Частые ошибки:
1. Забыли WHERE — и вставили весь набор, включая ненужное.
2. Не проверили SELECT — и получили не те данные.
3. Не учли дубликаты — и получили ошибки или лишние строки.
4. Совпали ID-шники — и нарушили целостность данных.

🧠 SQL-инсайты:
1. Можно использовать JOIN в SELECT — перенос с объединением.
2. Можно использовать CASE, чтобы пересчитывать данные на лету.
3. LIMIT полезен при вставке порциями.
4.Поддерживается во всех основных СУБД (MySQL, PostgreSQL, SQL Server, Oracle).

ПРИМЕР 1: копирование всех данных
INSERT INTO employees_backup
SELECT * FROM employees;

Что здесь происходит:
1. SELECT * FROM employees — выбираются все строки и все столбцы из таблицы employees.
2. INSERT INTO employees_backup — полученные строки вставляются в таблицу employees_backup.

❗️ Таблицы employees и employees_backup должны иметь одинаковую структуру — одинаковые столбцы в том же порядке и с совместимыми типами данных.

ПРИМЕР 2: выборочная вставка (фильтрация)
INSERT INTO orders_archive
SELECT * FROM orders
WHERE order_date < CURDATE() - INTERVAL 1 YEAR;

Что происходит:
1. SELECT * FROM orders — берутся все заказы.
2. WHERE order_date < CURDATE() - INTERVAL 1 YEAR — фильтрация: только те заказы, которым больше года.
3. Результат вставляется в orders_archive.

Это пример архивации старых данных — очень частая задача в реальной работе с базами.

ПРИМЕР 3: агрегация и вставка
INSERT INTO sales_summary (category, total_sales)
SELECT category, SUM(amount)
FROM sales
GROUP BY category;

Что делает запрос:
1. SELECT category, SUM(amount) — для каждой категории считается общая сумма продаж.
2. GROUP BY category — группирует строки по категориям.
3. INSERT INTO sales_summary (...) — вставляет результат в таблицу итогов.

В INSERT INTO перечислены имена столбцов, куда вставляются значения. Это повышает читаемость и защищает от ошибок при изменении структуры таблиц.

ПРИМЕР 4: выборка с JOIN
INSERT INTO newsletter_subscribers (user_id, user_name)
SELECT u.id, u.name
FROM users AS u
JOIN subnoscriptions AS s ON u.id = s.user_id
WHERE s.active = 1;

Что происходит по шагам:
JOIN объединяет таблицы users и subnoscriptions по user_id.
WHERE s.active = 1 — выбирает только активных подписчиков.
SELECT u. id, u. name — выбираем только нужные поля.
INSERT INTO newsletter_subscribers (...) — вставляем их в целевую таблицу.

Это пример массового импорта данных в отдельный список.

💡Вывод
INSERT INTO ... SELECT — это не просто способ скопировать данные, а инструмент для построения гибких потоков данных между таблицами. Это основа работы с отчетами, витринами, архивами и резервным копированием.

🔁 Делись с коллегами — особенно с теми, кто до сих пор вставляет данные вручную через VALUES

#Операторы_и_работа_с_данными

📱 Подписаться на канал | Курс автора по SQL DDL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👾6