7786
Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Автор: @energy_it
🖥 Как гарантировать одну активную запись?
Во многих системах есть правило: у пользователя, товара или сущности должна быть только одна активная запись. Если проверять это в коде, при конкурентных запросах правило легко нарушается.
Сегодня в гайде:
• Почему логика обновить + вставить ломается;
• Как зафиксировать правило на уровне базы;
• Как условный уникальный индекс предотвращает дубликаты.
NULLIF в SQL: простой способ не словить деление на ноль!
Очень частая задача в SQL — нужно что-то на что-то поделить. Например, посчитать средний чек, конверсию или процент выполнения.
Есть таблица:
sales(id, revenue, orders_count)
SELECT
id,
revenue / orders_count AS avg_order_value
FROM sales;
orders_count = 0, начинаются проблемы: в ряде СУБД такой запрос упадёт с ошибкой.NULLIF:SELECT
id,
revenue / NULLIF(orders_count, 0) AS avg_order_value
FROM sales;
NULLIF(orders_count, 0) вернёт: orders_count, если это не ноль; NULL, если это ноль.SELECT
id,
COALESCE(revenue / NULLIF(orders_count, 0), 0) AS avg_order_value
FROM sales;
SELECT
id,
success_count * 100.0 / NULLIF(total_count, 0) AS success_percent
FROM stats;
CASE:SELECT
id,
CASE
WHEN orders_count = 0 THEN NULL
ELSE revenue / orders_count
END AS avg_order_value
FROM sales;
NULLIF обычно короче и читается быстрее.SELECT
SUM(revenue) / NULLIF(SUM(orders_count), 0) AS avg_order_value
FROM sales;
SELECT
AVG(revenue / NULLIF(orders_count, 0)) AS avg_order_value
FROM sales;
AVG пропускает NULL.NULLIF(x, 0) — приём, который в реальных запросах спасает. Особенно когда хочется не просто чтобы не упало, а чтобы результат оставался корректным по смыслу.
Индекс с INCLUDE: уменьшаем чтение таблицы!
Даже если у вас есть индекс, PostgreSQL часто всё равно идёт в таблицу за остальными колонками — это лишний I/O, особенно на больших данных:
CREATE INDEX idx_orders_user_created
ON orders (user_id, created_at DESC)
INCLUDE (total, status);
INCLUDE добавляет дополнительные колонки в индекс (payload), но они не участвуют в поиске и сортировке, часто это выгоднее, чем делать их частью ключа:SELECT user_id, created_at, total, status
FROM orders
WHERE user_id = 42
ORDER BY created_at DESC
LIMIT 1;
Index Only Scan, уменьшая или исключая обращения к таблице (heap):EXPLAIN ANALYZE SELECT ...
Index Only Scan (иногда с Heap Fetches) вместо Index Scan — это значит, что обращения к таблице сокращены или отсутствуют.
DISTINCT — убираем дубликаты прямо в SQL!
Иногда таблица содержит повторы, а нам нужны только уникальные строки. DISTINCT позволяет легко отфильтровать дубликаты на уровне запроса — без дополнительной логики.
Выберем все уникальные города из таблицы клиентов:
SELECT DISTINCT city FROM customers;
SELECT DISTINCT country, city FROM customers;
SELECT COUNT(DISTINCT city) FROM customers;
SELECT DISTINCT ON (user_id) *
FROM logins
ORDER BY user_id, login_time DESC;
DISTINCT полезен для отчётов, списков, фильтрации и аналитики. Но помните: он влияет на производительность — особенно при работе с большими таблицами.
Курсы по кибербез, белый хакинг, социальная инженерия, безопасность
ИБ Книга — Более 1660 русскоязычных книг по ИБ и Социальной Инженерии можно найти на канале.
no system is safe // cybersec — один из древнейших ресурсов по информационной безопасности в рунете. Книги, курсы, полезные тулсы, уроки по Linux, новости клирнета и даркнета.
Python и 1000 программ — уроки по Python. Python мы будем использовать для создания OSINT софта.
Весь материал на каналах в общем доступе. Ничего лишнего
🖥 Oracle SQL: основные строковые функции!Основные функции обработки строк в Oracle SQL: извлечение подстрок, определение позиции подстроки, вычисление длины строки, преобразование регистра, удаление лишних символов по краям, замена фрагментов текста и дополнение строки до заданной длины.
➡️ SQL Ready | #шпора
PostgreSQL: CONCAT_WS, если нужно нормально собрать строку из колонок с NULL!
Частая мелочь в SQL — собрать одну строку из нескольких полей. Например, имя пользователя из first_name, middle_initial, last_name.
Таблица условно такая:
users(id, first_name, middle_initial, last_name)
SELECT first_name || ' ' || middle_initial || ' ' || last_name
FROM users;
middle_initial = NULL, то результат будет не Emily Johnson, а просто NULL.CONCAT_WS:SELECT CONCAT_WS(' ', first_name, middle_initial, last_name)
FROM users;CONCAT_WS склеивает значения через разделитель и просто пропускает NULL.middle_initial = 'A': Emily A Johnson. Если middle_initial = NULL: Emily Johnson.CONCAT_WS пропускает именно NULL. Пустая строка не игнорируется.COALESCE, например так:SELECT
COALESCE(first_name || ' ', '') ||
COALESCE(middle_initial || ' ', '') ||
COALESCE(last_name, '')
FROM users;
CONCAT_WS обычно самый нормальный вариант: и короче, и читается лучше.
💡 SQL by Example — SQL-шпаргалка с примерами запросов!
Здесь разобраны реальные примеры запросов: выборки, фильтрация, JOIN-ы, подзапросы, агрегации и другие ключевые конструкции, которые чаще всего используются при работе с базами данных. Формат максимально простой: пример, объяснение, результат, поэтому можно быстро понять, как работает конкретный запрос и сразу применить его в своих задачах.
Оставляю ссылочку: GitHub 📱
Ждал меня? Признавайся…
А я уже собрал все ИИ новости и инструменты в одном telegram-канале. Как ими пользоваться, как адаптировать под разные профессии, все тут. Даже твоя бабушка поймет 😎
Подпишись. Пользуйся.
📂 Напоминалка по типам серверов!
Например, DNS Server помогает найти нужный IP по доменному имени, а Proxy Server может скрыть тебя от внешней сети.
На картинке — 6 типов серверов, которые стоит понимать каждому разработчику.
Сохрани, чтобы не забыть!
➡ SQL Ready | #ресурс
Передавайте списки значений через массивы вместо длинных IN!
Когда из приложения нужно передать список id в SQL, многие пишут IN (... , ... , ...), что увеличивает текст SQL и усложняет работу с prepared statements:
WHERE id IN (1,2,3,4,5,6,7)
ANY — это короче и позволяет избежать генерации динамического SQL:WHERE id = ANY($1)
SELECT *
FROM users
WHERE email = ANY($1);
($1::bigint[]), а также помнить, что NULL внутри массива влияет на результат сравнения.batch-запросов, API-фильтров и массовых выборок, где количество значений может сильно меняться.
SEMI JOIN через EXISTS — как корректно проверять наличие связанных строк!
Частая задача в SQL — выбрать строки из одной таблицы, если в другой таблице существует хотя бы одна связанная запись.
Таблицы:
customers(id, name)
orders(id, customer_id, created_at)
JOIN:SELECT
c.id,
c.name
FROM customers c
JOIN orders o
ON o.customer_id = c.id;
DISTINCT:SELECT DISTINCT
c.id,
c.name
FROM customers c
JOIN orders o
ON o.customer_id = c.id;
JOIN формирует строки для каждого совпадения, а DISTINCT затем устраняет повторяющиеся значения.customers, если существует хотя бы одна связанная строка в orders.EXISTS:SELECT
c.id,
c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
);
orders, связанной с текущим клиентом.EXISTS является естественным инструментом для проверки существования строк.SELECT
c.id,
c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
AND o.created_at >= '2025-01-01'
);
EXISTS не возвращает данные из подзапроса — он только проверяет факт существования строки.SELECT 1
SELECT *
EXISTS список выбираемых выражений не влияет на результат.EXISTS — стандартный и выразительный способ реализовать semi join. Он точно отражает намерение запроса и часто позволяет оптимизатору построить более эффективный план выполнения.
Атомарное перемещение данных между таблицами!
Иногда нужно архивировать старые данные: удалить их из основной таблицы и одновременно сохранить в архиве. Многие делают это двумя запросами (INSERT => DELETE):
DELETE FROM orders
RETURNING *
RETURNING позволяет сразу вернуть удалённые строки как результирующий набор, не выполняя повторный SELECT.WITH moved AS (...)
CTE превращает результат удаления во временный набор данных, который можно использовать в следующей операции:INSERT INTO orders_archive
SELECT * FROM moved;
🖥 Анализ средней длительности сессий пользователей по устройствам!
В этой задаче напишем SQL-запрос, который поможет вычислить среднее время сессии для пользователей на разных устройствах за последние 30 дней.
Что делаем:
• Фильтруем сессии по времени и устройствам.
• Считаем длительность каждой сессии.
• Группируем и находим среднее время по типам устройств.
Агрегирование по группам с оконными функциями!
Когда нужно посчитать агрегаты по группе и при этом сохранить исходные строки, многие делают подзапрос с GROUP BY и потом джойнят его обратно:
SUM(o.total) OVER (PARTITION BY o.user_id)
GROUP BY, ни повторное соединение:AVG(o.total) OVER (PARTITION BY o.user_id)
COUNT(*) OVER (PARTITION BY o.user_id)
❤️ Use The Index, Luke — полезный ресурсов по оптимизации SQL!
Это гайд по производительности SQL, где подробно объясняется, как работают индексы и как с их помощью ускорять запросы. Материал построен с нуля и ориентирован именно на разработчиков, без лишней теории и перегруженной терминологии. Всё объясняется через практику и примеры.
📌 Оставляю ссылочку: use-the-index-luke.com
➡️ SQL Ready | #ресурс
👍 SQL Cheat Sheet — удобнейшая и информативная шпаргалка!
Этот компактный и понятный справочник по SQL, где собраны основные команды, конструкции и паттерны, которые используются в работе. Всё оформлено с примерами, поэтому можно быстро вспомнить синтаксис или найти нужную команду без долгого поиска. Отлично подходит как справочник в работе, для повторения базы и подготовки к собеседованиям.
Оставляю ссылочку: GitHub 📱
📂 Напоминалка по типам баз данных!
Например, реляционные базы используют строгую структуру таблиц и отлично подходят для транзакций, а NoSQL — гибкие и масштабируемые, подходят для высоконагруженных приложений.
На картинке — 4 типа баз данных, их особенности, преимущества и где их лучше применять.
Сохрани, чтобы не забыть!
➡️ SQL Ready | #ресурс
Совет на 2026 год — переходите в ML.
Пока обычные разрабы конкурируют с ИИ-копилотами, ML-инженеры эти самые нейронки создают.
В эпоху нейростей это самые востребованые люди в мире программирования. Зарплаты мидлов начинаются от 250 000 ₽, а у сеньоров в BigTech доходят до 700 000 ₽.
А чтобы освоить его всего за 4 месяца без лишней суеты — изучите канал Артема Алехина.
Его бэкграунд: Руководитель команды в Сбере, валютная удаленка. К 22 годам вышел на доход 1 000 000+ ₽ в месяц.
На канале вы найдёте:
— Всё про самые востребованные стеки(Python, ИИ-агенты, NLP) и почему математика — это не страшно, если учить только нужное.
— Как оформить резюме, чтобы оно пролетало через любые LLM-фильтры и ATS-системы прямо к тимлидам.
— Скрипты переговоров, которые помогли его ученикам прыгнуть с 0 до 360к всего за 8 месяцев.
Во времена острой нехватки ML-разработчиков, это лучшее время, чтобы перекатиться. Переходи и изучай: /channel/+zFlLy16mPM40Zjc6
🖥 Быстрый ориентир по SQL-командам!
Когда нужно создать таблицу или изменить её структуру — берём DDL. Хотим изменить данные внутри — используем DML. А если нужно просто вытянуть информацию — поможет DQL с её незаменимым select.
Полезно держать под рукой, чтобы не забыть!
➡️ SQL Ready | #ресурс
❤️ Полезную статью нашёл на Хабре: «Почему SUM() OVER (ORDER BY ...) иногда считает “неправильно”: разбираем оконные фреймы в SQL»!
В этой статье:• Объясняется, как на самом деле работают оконные функции в SQL и почему результаты иногда отличаются от ожидаемых;
• Разбираются ключевые типы оконных фреймов — ROWS, RANGE и GROUPS, а также их влияние на вычисления;
• Показано, как правильно задавать границы окна (UNBOUNDED PRECEDING, CURRENT ROW, FOLLOWING) для накопительных итогов, скользящих средних и аналитических запросов.
🔊 Продолжайте читать на Habr!
На Stepik добавили курс «Linux с нуля»
Этот курс закрывает всю обязательную Linux-базу для работы в IT. Подойдёт для:
- разработчиков
- девопсов и админов
- специалистов по данным и ML
- специалистов поддержки и сопровождения
- тестировщиков и безопасников
READY30»: открыть курс на Stepik
Читать полностью…
Получение top-N строк с учётом равных значений!
Иногда нужно получить не просто N строк, а все записи, которые имеют такое же значение сортировки, как и последняя строка в выборке.
Это полезно для топ-продаж, логов и аналитики.
FETCH FIRST 5 ROWS ONLY
LIMIT / FETCH возвращает ровно N строк и может «обрезать» записи с таким же значением сортировки.WITH TIES возвращает все строки, у которых значение ORDER BY совпадает с последней строкой результата:FETCH FIRST 5 ROWS WITH TIES
ORDER BY score DESC
FETCH FIRST 10 ROWS WITH TIES
WITH TIES не заменяет RANK() / DENSE_RANK(), если нужен полноценный рейтинг с номером места. Также проверьте синтаксис в вашей СУБД (например, в SQL Server используется TOP ... WITH TIES).
📂 Напоминалка по архитектуре PostgreSQL и MySQL!
PostgreSQL работает через процессы и shared memory, а системой управляет Postmaster и фоновые процессы. MySQL использует слоистую архитектуру: подключение, обработка SQL и storage engine (например InnoDB).
На картинке — основные компоненты и различия архитектуры двух популярных СУБД.
Сохрани, чтобы не забыть!
➡️ SQL Ready | #ресурс
VACUUM — чистим таблицу и ускоряем работу базы!
В большинстве СУБД удалённые или обновлённые строки не удаляются мгновенно, а остаются как «мертвые» записи. Со временем это замедляет запросы и увеличивает размер таблиц — нужна очистка.
Сначала удаляем устаревшие записи из таблицы:
DELETE FROM sessions WHERE expired = true;
VACUUM ANALYZE sessions;
VACUUM VERBOSE sessions;
VACUUM поддерживает производительность и точность планов запросов.
🐱 Крутейшая статья вышла на Хабре: «Научил ИИ-агента помнить важное и забывать лишнее в SQLite»!
В этой статье:• Разбирается, почему классический RAG плохо подходит для долгоживущих AI-агентов;
• Показана архитектура когнитивной памяти на SQLite: граф узлов и рёбер, сущности, гибридный поиск и механизм разрешения конфликтов знаний;
• Объясняется, как реализовать память агента с механизмом забывания и консолидацией фактов.
🔊 Продолжайте читать на Habr!
❤️ RusauSQL — подробный учебник по SQL для тестировщиков и разработчиков!
Это большой гайд по SQL, где последовательно объясняется, как работать с базами данных и писать запросы. На сайте разбираются фундаментальные вещи: что такое SQL, как устроены таблицы и базы данных, как выполнять запросы, проверять данные и взаимодействовать с сервером через язык запросов. Отличный ресурс, если хочешь разобраться в SQL с практической стороны и понять работу баз данных.
📌 Оставляю ссылочку: rusau.net
➡️ SQL Ready | #сайт
📂 Напоминалка по SQL JOIN!
Например, LEFT JOIN позволяет получить все строки из левой таблицы, даже если соответствующих записей в правой таблице нет, а FULL OUTER JOIN возвращает все строки из обеих таблиц, заполняя отсутствующие значения NULL.
На изображении показаны 4 основных типа SQL JOIN, которые чаще всего используются при объединении данных из нескольких таблиц.
📌 Сохрани, чтобы не потерять!
➡️ SQL Ready | #ресурс
💡 Rows — умные таблицы с встроенным ИИ!
Сервис для работы с данными в формате таблиц (аналог Excel / Google Sheets) с интегрированными AI-инструментами. Позволяет анализировать данные, создавать формулы по описанию и подтягивать информацию из интернета и API. Подходит для аналитики, автоматизации и обработки больших массивов данных.
📌 Оставляю ссылочку: rows.com
➡️ SQL Ready | #ресурс
☕️ Полезную статью нашёл на Хабре: «Инженерная история: добавляем 3-ю СУБД в карточный процессинг»!
В этой статье:• Разобрано, зачем в высоконагруженной системе может понадобиться сразу несколько СУБД и как между ними строится абстрактный слой доступа к данным;
• Показан опыт интеграции распределённой базы данных YDB в существующую архитектуру;
• Разбираются технические нюансы: батч-операции, строгая типизация запросов, особенности драйверов и результаты нагрузочного тестирования.
🔊 Продолжайте читать на Habr!