SQL Ready | Базы Данных
Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc
Show more📈 Analytical overview of Telegram channel SQL Ready | Базы Данных
Channel SQL Ready | Базы Данных (@sql_ready) in the Russian language segment is an active participant. Currently, the community unites 17 754 subscribers, ranking 7 324 in the Technologies & Applications category and 37 073 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 17 754 subscribers.
According to the latest data from 19 October, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 712 over the last 30 days and by 32 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 12.57%. Within the first 24 hours after publication, content typically collects 5.99% reactions from the total number of subscribers.
- Post reach: On average, each post receives 2 230 views. Within the first day, a publication typically gains 1 062 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 23.
- Thematic interests: Content is focused on key topics such as sql, строка, users, индекс, user_id.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc”
Thanks to the high frequency of updates (latest data received on 20 October, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
OR 1=1 может вернуть все данные из таблицы, а blind SQLi позволяет вытаскивать информацию даже тогда, когда приложение не показывает ошибки и результаты запросов.
На картинке — основные типы SQL-инъекций, которые важно знать при работе с базами данных и backend-логикой.
Сохрани, чтобы не забыть!
➡️ SQL Ready | #ресурс• LEFT JOIN — соединяем таблицы, чтобы сохранить всех клиентов, даже тех, у кого нет заказов. • WHERE o,id IS NULL — отбираем только тех, для кого заказов не найдено. • SELECT — выводим имя, email и дату регистрации.➡ SQL Ready | #задача
Loading … ██████████████] 99%Роскомнадзору дали карт-бланш на блокировки, а «белые списки» сайтов тестируют уже в десятках регионов. И гайки будут закручиваться только сильнее. Чтобы в одночасье не лишиться доступа к свободному Интернету, просто сохрани Only Hack. Тут профессиональный хакер делится фишками, с которыми доступ к глобальной сети у тебя будет даже в случае ядерного апокалипсиса. Не жди момента «Х». Перестрахуйся подпиской.
NOT IN в SQL можно получить логически неверный результат без ошибок выполнения. Причина — трёхзначная логика и наличие NULL в данных.
Представим таблицы:
customers(id)
orders(id, customer_id)
Нужно найти клиентов, у которых нет заказов.
Интуитивный вариант:
SELECT id
FROM customers
WHERE id NOT IN (
SELECT customer_id
FROM orders
);
Если подзапрос возвращает хотя бы одно значение NULL, результат этого запроса будет пустым, даже если клиенты без заказов существуют.
Это происходит потому, что NOT IN сводится к серии сравнений, а любое сравнение с NULL возвращает неопределённый результат.
Попытка исправить ситуацию фильтрацией:
SELECT id
FROM customers
WHERE id NOT IN (
SELECT customer_id
FROM orders
WHERE customer_id IS NOT NULL
);
Формально запрос корректен, но требует постоянного контроля и легко ломается при изменении подзапроса.
Надёжный вариант — использовать NOT EXISTS:
SELECT c.id
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
);
NOT EXISTS корректно обрабатывает NULL и предназначен именно для проверок отсутствия связанных строк.
🔥 Используй NOT EXISTS для анти-джойнов и проверок отсутствия данных, а NOT IN — только при полном контроле результата подзапроса.
➡️ SQL Ready | #практикаUPSERT обновляет строку всегда, даже если данные не изменились — это лишние блокировки, WAL и autovacuum.
PostgreSQL позволяет сделать условный UPDATE прямо в ON CONFLICT:
ON CONFLICT (id) DO UPDATE
...
WHERE users.email IS DISTINCT FROM EXCLUDED.email
OR users.name IS DISTINCT FROM EXCLUDED.name;
Если данные совпадают — UPDATE не выполняется вообще.
EXCLUDED — это “новая” версия строки, users.* — текущая версия в таблице.
users.col IS DISTINCT FROM EXCLUDED.col
🔥 Корректно работает даже с NULL и не попадает в ловушки трёхзначной логики.
➡️ SQL Ready | #советFILTER, позволяющий задавать условия отдельно для каждой агрегатной функции, не влияя на весь запрос.
Представим таблицу заказов:
orders(id, customer_id, amount, status)
Посчитаем общее количество заказов и количество завершённых:
SELECT
COUNT(*) AS total_orders,
COUNT(*) FILTER (WHERE status = 'completed') AS completed_orders
FROM orders;
FILTER применяется непосредственно к агрегатной функции и ограничивает только те строки, которые участвуют в её расчёте.
Добавим несколько метрик в одном запросе:
SELECT
COUNT(*) AS total_orders,
COUNT(*) FILTER (WHERE status = 'completed') AS completed_orders,
COUNT(*) FILTER (WHERE status = 'canceled') AS canceled_orders,
SUM(amount) FILTER (WHERE status = 'completed') AS completed_amount
FROM orders;
Каждая агрегатная функция имеет собственное условие, а все значения считаются за один проход по данным — без подзапросов и лишней логики.
FILTER можно использовать с любыми агрегатами:
AVG(amount) FILTER (WHERE status = 'completed')
MAX(amount) FILTER (WHERE status = 'completed')
MIN(amount) FILTER (WHERE status = 'completed')
🔥 Важно помнить: FILTER работает только с агрегатными функциями и применяется внутри SELECT, дополняя, а не заменяя WHERE и GROUP BY.
➡️ SQL Ready | #практикаОставляю ссылочку: GitHub 📱➡️ SQL Ready | #репозиторий
• Как считать несколько уровней агрегации за один проход по данным; • Как отличать строки-итоги от обычных данных; • Почему такой подход проще поддерживать и масштабировать.Приём, который делает отчёты чище, быстрее и предсказуемее при росте требований. ➡️ SQL Ready | #гайд
email <> 'admin@example.com'
не вернёт строки с email IS NULL — результат будет UNKNOWN.
Для корректного сравнения используйте IS DISTINCT FROM:
email IS DISTINCT FROM 'admin@example.com'
Оно работает так, как ожидаешь:
NULL ≠ любое значение
NULL = NULL
Результат всегда TRUE или FALSE (без UNKNOWN).
То же самое для проверки изменений:
old_value IS DISTINCT FROM new_value
🔥 Это инструмент не для синтаксиса, а для корректности данных.
➡️ SQL Ready | #советDISTINCT и GROUP BY. Результат может выглядеть одинаково, но назначение и смысл у этих конструкций разные.
Представим таблицу заказов:
orders(id, customer_id, product_id)
Найдём всех уникальных клиентов, которые делали заказы:
SELECT DISTINCT customer_id
FROM orders;
DISTINCT удаляет дубликаты по всему набору выбранных колонок в результирующем наборе — без группировок и агрегаций.
Сделаем то же самое через GROUP BY:
SELECT customer_id
FROM orders
GROUP BY customer_id;
Результат будет тем же, но семантически запрос другой: явно группируем строки по customer_id. В простых случаях оптимизатор часто строит одинаковый план, но логика запроса уже «про группы».
GROUP BY становится необходимым, когда появляются агрегаты.
Посчитаем количество заказов на каждого клиента:
SELECT customer_id, COUNT(*) AS orders_count
FROM orders
GROUP BY customer_id;
В этом запросе GROUP BY обязателен, потому что мы одновременно выбираем агрегат (COUNT(*)) и неагрегированное поле (customer_id).
Частая ошибка — смешивать DISTINCT и агрегаты без GROUP BY:
SELECT DISTINCT customer_id, COUNT(*)
FROM orders;
Такой запрос в стандартном SQL некорректен: неагрегированные поля должны присутствовать в GROUP BY. В зависимости от СУБД и режима он либо не выполнится, либо вернёт неопределённый результат.
Корректный вариант:
SELECT customer_id, COUNT(*) AS orders_count
FROM orders
GROUP BY customer_id;
🔥 Используй DISTINCT для простого удаления дублей, а GROUP BY — когда нужна агрегация, расчёты по группам или HAVING.
➡️ SQL Ready | #практикаBloom Filter позволяет быстро проверить, встречался ли элемент ранее, а HyperLogLog помогает оценить количество уникальных значений, не храня все данные целиком.
На картинке — 6 структур данных, которые стоит держать под рукой при проектировании backend-систем, аналитики и highload-сервисов.
Сохрани, чтобы не забыть!
➡️ SQL Ready | #ресурсadvisory locks — логические блокировки, не привязанные к таблицам или строкам.
SELECT pg_advisory_xact_lock(42);
Пока транзакция активна, другие процессы с тем же ключом будут ожидать.
Ключ — это просто число. Можно использовать user_id, order_id, хеш или tenant_id.
SELECT pg_advisory_xact_lock(user_id);
🔥 Это превращает PostgreSQL в механизм распределённой синхронизации. После COMMIT или ROLLBACK блокировка снимается автоматически.
➡️ SQL Ready | #советCREATE TABLE documents (
id INT PRIMARY KEY,
doc_key VARCHAR(500) NOT NULL
);
Добавим префиксный индекс. Индексируются только первые 20 символов:
CREATE INDEX idx_doc_key_prefix
ON documents (doc_key(20));
Если фильтровать данные по фиксированному началу строки, MySQL использует префиксный индекс:
SELECT id
FROM documents
WHERE doc_key LIKE 'INV-2024-%';
Важно: индекс применяется только если шаблон начинается без ведущего %. Например, LIKE '%2024%' уже не сможет его использовать.
Пример с email — если полная индексация не нужна:
CREATE INDEX idx_email_prefix
ON users (email(16));
🔥 Ограничения: префикс должен быть достаточно селективным, иначе польза минимальна. Такие индексы практически не подходят для сортировки или группировки по полному полю, так как индекс содержит лишь его часть.
➡️ SQL Ready | #практика