sql_ready | Unsorted

Telegram-канал sql_ready - SQL Ready | Базы Данных

7786

Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Автор: @energy_it

Subscribe to a channel

SQL Ready | Базы Данных

Полуинтервалы вместо BETWEEN для корректных и быстрых диапазонов!

BETWEEN кажется удобным, но он включает обе границы, из-за чего легко ловятся баги на датах и времени, особенно с timestamp:

WHERE created_at BETWEEN '2025-01-01' AND '2025-01-31'


Такой код пропустит всё, что позже '2025-01-31 00:00:00', и это одна из самых частых, незаметных ошибок в аналитике:
WHERE created_at >= '2025-01-01'
AND created_at < '2025-02-01'


Полуинтервал [start, end) работает предсказуемо для любых типов времени, не ломается на миллисекундах и хорошо ложится на индексы:
WHERE ts >= now()
AND ts < now() + interval '1 day'


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

➡️ SQL Ready | #совет

Читать полностью…

SQL Ready | Базы Данных

❤️ SQL Anti-Patterns — ошибки в SQL, которые допускают почти все!

Этот репозиторий разбирает типичные ошибки и плохие практики в SQL, с которыми сталкиваются разработчики в реальных проектах. Здесь показано, как не стоит писать запросы, и даются более правильные и эффективные альтернативы. Отлично подходит для оптимизации запросов и подготовки к собеседованиям.

Оставляю ссылочку: GitHub 📱


➡️ SQL Ready | #репозиторий

Читать полностью…

SQL Ready | Базы Данных

📂 Напоминалка по масштабированию баз данных!

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

На картинке — основные стратегии масштабирования, которые используются в реальных системах.

Сохрани, чтобы держать под рукой!

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

🖥 Напоминалка по SQL-командам!

Например, GRANT даёт пользователю права на таблицу, а ROLLBACK отменяет изменения в рамках транзакции.

На картинке — 5 групп SQL-команд: от определения структуры до управления доступом.

Сохрани, чтобы не забыть!

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

😎 Отыскал для вас LabEx — прокачка SQL в формате игры!

Вместо скучной теории — реальные задания, которые решаешь прямо в браузере. Всё с подсказками, примерами и моментальной проверкой. Отлично, чтобы быстро вкатиться в SQL или прокачать скилл.

📌 Оставляю ссылочку: labex.io

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

❤️ Use The Index, Luke — полезный ресурсов по оптимизации SQL!

Это гайд по производительности SQL, где подробно объясняется, как работают индексы и как с их помощью ускорять запросы. Материал построен с нуля и ориентирован именно на разработчиков, без лишней теории и перегруженной терминологии. Всё объясняется через практику и примеры.

📌 Оставляю ссылочку: use-the-index-luke.com

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

👍 SQL Cheat Sheet — удобнейшая и информативная шпаргалка!

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

Оставляю ссылочку: GitHub 📱


➡️ SQL Ready | #репозиторий

Читать полностью…

SQL Ready | Базы Данных

📂 Напоминалка по типам баз данных!

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

На картинке — 4 типа баз данных, их особенности, преимущества и где их лучше применять.

Сохрани, чтобы не забыть!

➡️ SQL Ready | #ресурс

Читать полностью…

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 Ready | Базы Данных

🖥 Быстрый ориентир по SQL-командам!

Когда нужно создать таблицу или изменить её структуру — берём DDL. Хотим изменить данные внутри — используем DML. А если нужно просто вытянуть информацию — поможет DQL с её незаменимым select.

Полезно держать под рукой, чтобы не забыть!

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

❤️ Полезную статью нашёл на Хабре: «Почему SUM() OVER (ORDER BY ...) иногда считает “неправильно”: разбираем оконные фреймы в SQL»!

В этой статье:
• Объясняется, как на самом деле работают оконные функции в SQL и почему результаты иногда отличаются от ожидаемых;
• Разбираются ключевые типы оконных фреймов — ROWS, RANGE и GROUPS, а также их влияние на вычисления;
• Показано, как правильно задавать границы окна (UNBOUNDED PRECEDING, CURRENT ROW, FOLLOWING) для накопительных итогов, скользящих средних и аналитических запросов.


🔊 Продолжайте читать на Habr!


➡️ SQL Ready | #статья

Читать полностью…

SQL Ready | Базы Данных

На Stepik добавили курс «Linux с нуля»

Этот курс закрывает всю обязательную Linux-базу для работы в IT. Подойдёт для:

- разработчиков
- девопсов и админов
- специалистов по данным и ML
- специалистов поддержки и сопровождения
- тестировщиков и безопасников


Внутри 20+ модулей: от установки Linux и работы с файлами до сетей, прав, дисков, процессов, автоматизации на Bash и многого другого. Всё сразу закрепляется на практике (200+ заданий с автопроверкой)

Материал подаётся понятным языком, шаг за шагом, на реальных примерах и с наглядными схемами

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

В ближайшие 48ч курс доступен со скидкой 30% по промокоду «READY30»: открыть курс на Stepik

Читать полностью…

SQL Ready | Базы Данных

Получение top-N строк с учётом равных значений!

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

Это полезно для топ-продаж, логов и аналитики.

FETCH FIRST 5 ROWS ONLY


Обычный LIMIT / FETCH возвращает ровно N строк и может «обрезать» записи с таким же значением сортировки.

WITH TIES возвращает все строки, у которых значение ORDER BY совпадает с последней строкой результата:
FETCH FIRST 5 ROWS WITH TIES


Это удобно для построения top-N выборок, где несколько строк могут делить одно и то же место:
ORDER BY score DESC
FETCH FIRST 10 ROWS WITH TIES


WITH TIES не заменяет RANK() / DENSE_RANK(), если нужен полноценный рейтинг с номером места. Также проверьте синтаксис в вашей СУБД (например, в SQL Server используется TOP ... WITH TIES).

🔥 Такой приём позволяет строить top-выборки без дополнительных подзапросов и оконных функций.

➡️ SQL Ready | #совет

Читать полностью…

SQL Ready | Базы Данных

📂 Напоминалка по архитектуре PostgreSQL и MySQL!

PostgreSQL работает через процессы и shared memory, а системой управляет Postmaster и фоновые процессы. MySQL использует слоистую архитектуру: подключение, обработка SQL и storage engine (например InnoDB).

На картинке — основные компоненты и различия архитектуры двух популярных СУБД.

Сохрани, чтобы не забыть!

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

VACUUM — чистим таблицу и ускоряем работу базы!

В большинстве СУБД удалённые или обновлённые строки не удаляются мгновенно, а остаются как «мертвые» записи. Со временем это замедляет запросы и увеличивает размер таблиц — нужна очистка.

Сначала удаляем устаревшие записи из таблицы:

DELETE FROM sessions WHERE expired = true;


Однако физически строки всё ещё занимают место.

Чтобы освободить пространство и обновить статистику, запускаем:
VACUUM ANALYZE sessions;


Для диагностики можно получить подробный отчёт о процессе очистки:
VACUUM VERBOSE sessions;


🔥 Регулярный VACUUM поддерживает производительность и точность планов запросов.

➡️ SQL Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

📂 Базовые структуры данных и их применение в системах!

Например, B-Tree используется в индексах для ускорения поиска, а Hash Table — в механизмах join’ов и кэширования.

На картинке — ключевые структуры данных и типичные сценарии их использования в реальных системах и базах данных.

Сохрани, чтобы держать под рукой!

➡️ SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

LIMIT без ORDER BY — почему результат нестабилен!

Есть таблица:

orders(id, customer_id, amount, created_at)


И вот такой запрос:
SELECT * FROM orders LIMIT 10;


Интуитивно хочется думать, что это первые 10 или последние 10. На деле — это просто неопределённые 10 строк в неопределённом порядке.

Без ORDER BY база не обязана возвращать данные в каком-то фиксированном порядке. Сегодня это один набор строк, завтра — другой. Особенно если поменялся план выполнения или появился индекс.

Типичный кейс — хочу последние заказы:
SELECT * 
FROM orders
ORDER BY created_at DESC
LIMIT 10;


Уже лучше: теперь это 10 самых новых по created_at.

Но тут есть тонкость — если несколько строк имеют одинаковый created_at, порядок между ними не детерминирован. Иногда это всплывает в самых неожиданных местах (например, в пагинации).

Поэтому обычно добавляют второй критерий:
SELECT * 
FROM orders
ORDER BY created_at DESC, id DESC
LIMIT 10;


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

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

OFFSET и его ограничения:
SELECT * 
FROM orders
ORDER BY created_at DESC, id DESC
LIMIT 10 OFFSET 20;


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

Поэтому в проде чаще используют keyset pagination:
SELECT * 
FROM orders
WHERE (created_at, id) < ('2026-01-10', 1050)
ORDER BY created_at DESC, id DESC
LIMIT 10;


Фактически: дай следующие записи после этой точки.

Работает быстрее и ведёт себя предсказуемо при изменениях данных (Важно: синтаксис с (col1, col2) поддерживается не во всех СУБД; универсальный вариант — через OR.)

И ещё частая ошибка:
SELECT * 
FROM orders
ORDER BY created_at
LIMIT 1;


Кажется, что это последняя запись, а по факту — самая старая (по умолчанию используется ASC в большинстве СУБД).

🔥 Вся суть: LIMIT отвечает только за количество. Порядок — это всегда ORDER BY. Без составного индекса (created_at, id) такие запросы на больших таблицах начинают ощутимо тормозить.

➡️ SQL Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

Использование расширенной статистики для повышения точности планировщика!

Бывает, что запрос очевидный, индексы есть, но PostgreSQL всё равно выбирает Seq Scan, потому что считает условия независимыми и сильно ошибается в кардинальности:

CREATE STATISTICS s_orders (dependencies)
ON user_id, status
FROM orders;


Extended statistics позволяют оптимизатору учитывать зависимости между колонками, например что у конкретного user_id почти всегда один и тот же status:
ANALYZE orders;


После сбора статистики PostgreSQL начинает правильно оценивать селективность комбинации условий, а не перемножать вероятности как будто они независимы:
EXPLAIN ANALYZE SELECT ...


🔥 Не меняешь код и индексы, но кардинально улучшаешь планы выполнения.

➡️ SQL Ready | #совет

Читать полностью…

SQL Ready | Базы Данных

CHECK-ограничения — валидация данных на уровне базы!

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

Представим, что мы хотим убедиться, что цена товара всегда больше нуля:

CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
name TEXT,
price NUMERIC(10,2),
CHECK (price > 0)
);


Теперь добавим ограничение, чтобы процент скидки был в пределах от 0 до 100:
ALTER TABLE discounts
ADD CONSTRAINT percent_range_chk
CHECK (percentage BETWEEN 0 AND 100);


И создадим таблицу событий, где дата начала всегда должна быть раньше даты окончания:
CREATE TABLE events (
id SERIAL PRIMARY KEY,
starts_at TIMESTAMP,
ends_at TIMESTAMP,
CHECK (starts_at < ends_at)
);


🔥 Но помните, что CHECK проверяет только вставляемые или обновлённые строки. Если вы добавляете ограничение в таблицу с данными, указывайте NOT VALID, чтобы временно обойти проверку.

➡️ SQL Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

🖥 Как гарантировать одну активную запись?

Во многих системах есть правило: у пользователя, товара или сущности должна быть только одна активная запись. Если проверять это в коде, при конкурентных запросах правило легко нарушается.

Сегодня в гайде:

Почему логика обновить + вставить ломается;

Как зафиксировать правило на уровне базы;

Как условный уникальный индекс предотвращает дубликаты.


Подход, который убирает класс ошибок с конкурентным доступом и делает данные консистентными независимо от нагрузки.

➡️ SQL Ready | #гайд

Читать полностью…

SQL Ready | Базы Данных

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, если это ноль.

Соответственно: если знаменатель не ноль — деление выполняется как обычно; если знаменатель ноль — получится NULL.

И это как раз правильное поведение. Потому что NULLIF не исправляет данные и не подменяет ноль каким-то удобным значением. Он просто говорит: в этой строке результат не определён.

Иногда после этого пишут так:
SELECT
id,
COALESCE(revenue / NULLIF(orders_count, 0), 0) AS avg_order_value
FROM sales;


Так делать можно, но только если 0 здесь действительно имеет смысл.

Потому что: NULL — значение не определено; 0 — значение определено и равно нулю. Это разные вещи. И подмена одного другим — уже не технический, а смысловой выбор.

Ещё пример:
SELECT
id,
success_count * 100.0 / NULLIF(total_count, 0) AS success_percent
FROM stats;


Почему именно 100.0, а не 100? Чтобы не получить целочисленное деление в тех СУБД, где дробная часть иначе отбросится.

То же самое можно записать и через 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) — приём, который в реальных запросах спасает. Особенно когда хочется не просто чтобы не упало, а чтобы результат оставался корректным по смыслу.

➡️ SQL Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

Индекс с 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;


Теперь все нужные поля есть в индексе, и PostgreSQL может выполнить запрос через Index Only Scan, уменьшая или исключая обращения к таблице (heap):
EXPLAIN ANALYZE SELECT ...


В плане вы увидите Index Only Scan (иногда с Heap Fetches) вместо Index Scan — это значит, что обращения к таблице сокращены или отсутствуют.

🔥 Один из практических бустов в read-heavy сценариях и частых API-запросах.

➡️ SQL Ready | #совет

Читать полностью…

SQL Ready | Базы Данных

DISTINCT — убираем дубликаты прямо в SQL!

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

Выберем все уникальные города из таблицы клиентов:

SELECT DISTINCT city FROM customers;


Теперь получим только уникальные пары "страна + город":
SELECT DISTINCT country, city FROM customers;


А вот как посчитать количество разных городов:
SELECT COUNT(DISTINCT city) FROM customers;


В PostgreSQL можно выбирать первую уникальную строку по группе значений:
SELECT DISTINCT ON (user_id) *
FROM logins
ORDER BY user_id, login_time DESC;


🔥 DISTINCT полезен для отчётов, списков, фильтрации и аналитики. Но помните: он влияет на производительность — особенно при работе с большими таблицами.

➡️ SQL Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

Курсы по кибербез, белый хакинг, социальная инженерия, безопасность

ИБ Книга
Более 1660 русскоязычных книг по ИБ и Социальной Инженерии можно найти на канале.

no system is safe // cybersec — один из древнейших ресурсов по информационной безопасности в рунете. Книги, курсы, полезные тулсы, уроки по Linux, новости клирнета и даркнета.

Python и 1000 программ уроки по Python. Python мы будем использовать для создания OSINT софта.

Весь материал на каналах в общем доступе. Ничего лишнего

Читать полностью…

SQL Ready | Базы Данных

🖥 Oracle SQL: основные строковые функции!

Основные функции обработки строк в Oracle SQL: извлечение подстрок, определение позиции подстроки, вычисление длины строки, преобразование регистра, удаление лишних символов по краям, замена фрагментов текста и дополнение строки до заданной длины.

➡️ SQL Ready | #шпора

Читать полностью…

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;


И тут важный момент: если хотя бы одно значение NULL, всё выражение тоже уйдёт в NULL.

То есть если 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 Ready | #практика

Читать полностью…

SQL Ready | Базы Данных

💡 SQL by Example — SQL-шпаргалка с примерами запросов!

Здесь разобраны реальные примеры запросов: выборки, фильтрация, JOIN-ы, подзапросы, агрегации и другие ключевые конструкции, которые чаще всего используются при работе с базами данных. Формат максимально простой: пример, объяснение, результат, поэтому можно быстро понять, как работает конкретный запрос и сразу применить его в своих задачах.

Оставляю ссылочку: GitHub 📱


➡️ SQL Ready | #репозиторий

Читать полностью…

SQL Ready | Базы Данных

Ждал меня? Признавайся…

А я уже собрал все ИИ новости и инструменты в одном telegram-канале. Как ими пользоваться, как адаптировать под разные профессии, все тут. Даже твоя бабушка поймет 😎

Подпишись. Пользуйся.

Читать полностью…

SQL Ready | Базы Данных

📂 Напоминалка по типам серверов!

Например, DNS Server помогает найти нужный IP по доменному имени, а Proxy Server может скрыть тебя от внешней сети.

На картинке — 6 типов серверов, которые стоит понимать каждому разработчику.

Сохрани, чтобы не забыть!

SQL Ready | #ресурс

Читать полностью…

SQL Ready | Базы Данных

Передавайте списки значений через массивы вместо длинных IN!

Когда из приложения нужно передать список id в SQL, многие пишут IN (... , ... , ...), что увеличивает текст SQL и усложняет работу с prepared statements:

WHERE id IN (1,2,3,4,5,6,7)


PostgreSQL умеет принимать массив и сравнивать его через ANY — это короче и позволяет избежать генерации динамического SQL:
WHERE id = ANY($1)


Приложение просто передаёт массив параметром, а текст запроса остаётся неизменным независимо от длины списка:
SELECT *
FROM users
WHERE email = ANY($1);


На практике полезно явно указывать тип массива ($1::bigint[]), а также помнить, что NULL внутри массива влияет на результат сравнения.

🔥 Этот паттерн особенно удобен для batch-запросов, API-фильтров и массовых выборок, где количество значений может сильно меняться.

➡️ SQL Ready | #совет

Читать полностью…
Subscribe to a channel