SQL Ready | Базы Данных
Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc
Ko'proq ko'rsatish📈 Telegram kanali SQL Ready | Базы Данных analitikasi
SQL Ready | Базы Данных (@sql_ready) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 17 709 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 7 345-o'rinni va Rossiya mintaqasida 37 222-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 17 709 obunachiga ega bo‘ldi.
17 Oktabr, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni 691 ga, so‘nggi 24 soatda esa 41 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 12.44% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 5.98% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 2 198 marta ko‘riladi; birinchi sutkada odatda 1 057 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 23 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent sql, строка, users, индекс, user_id kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 18 Oktabr, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
• Преобразуем интервалы в точки начала и конца, чтобы работать с ними как с потоком событий; • Посчитаем текущую нагрузку через накопительную сумму по времени; • Найдём момент максимального количества одновременных событий — пик нагрузки системы.Этот приём используется в мониторинге, аналитике, планировщиках и системах, где важно контролировать параллельную активность. ➡️ SQL Ready | #задача
• Показано, как в YDB обрабатывается SQL-запрос — от парсинга до распределённого исполнения по узлам;
• Разбирается, как устроены планировщик, оптимизатор и механизмы шардинга при работе с большими данными;
• Объясняется, как достигаются консистентность, отказоустойчивость и масштабируемость в распределённой базе.
🔊 Продолжайте читать на Habr!➡️ SQL Ready | #статья
orders(id, customer_id, amount)
order_items(id, order_id, product_id, quantity)
Допустим, хотим посчитать сумму заказов. На первый взгляд кажется, что такой запрос окей:
SELECT SUM(o.amount) AS total_revenue
FROM orders o
JOIN order_items i
ON i.order_id = o.id;
Но тут и начинается подвох.
Если у одного заказа 3 позиции в order_items, то строка из orders после JOIN повторится 3 раза. И o.amount тоже попадёт в расчёт 3 раза. В итоге сумма завышается. Это как раз тот самый fan-out: одна строка размножается после JOIN.
Быстрая проверка, есть ли проблема:
SELECT
COUNT(*) AS rows_after_join,
COUNT(DISTINCT o.id) AS unique_orders
FROM orders o
JOIN order_items i
ON i.order_id = o.id;
Если строк после JOIN стало больше, чем уникальных заказов, значит у вас fan-out по уровню orders. Что делать правильно — зависит от задачи.
Если вам нужна просто сумма по заказам, то JOIN вообще не нужен:
SELECT SUM(amount)
FROM orders;
Если JOIN нужен только для фильтрации, например по конкретному товару, безопаснее использовать EXISTS:
SELECT SUM(o.amount)
FROM orders o
WHERE EXISTS (
SELECT 1
FROM order_items i
WHERE i.order_id = o.id
AND i.product_id = 10
);
Почему это хорошо: гранулярность orders не ломается. Один заказ остаётся одной строкой.
Ещё нормальный вариант — сначала убрать дубли на стороне order_items:
SELECT SUM(o.amount)
FROM orders o
JOIN (
SELECT DISTINCT order_id
FROM order_items
WHERE product_id = 10
) i ON i.order_id = o.id;
Тут мы заранее приводим данные к уровню одна строка = один заказ, и только потом джойним.
А если задача вообще на уровне позиций, например нужно посчитать общее количество товаров, тогда считать надо уже по order_items:
SELECT SUM(i.quantity)
FROM order_items i;
То есть важный момент очень простой: агрегировать нужно на том уровне, где реально живёт ваша метрика.
Отдельно про популярный костыль:
SELECT SUM(DISTINCT o.amount)
FROM orders o
JOIN order_items i
ON i.order_id = o.id;
С виду кажется, что DISTINCT сейчас всё починит, на деле — нет. Почему это плохая идея: если у двух разных заказов одинаковый amount, один из них просто схлопнется; запрос начинает давать вроде бы правдоподобный, но неверный результат.
Ещё неприятнее, когда JOIN не один, а цепочка: orders — order_items — products — categories
Практический способ быстро это поймать — смотреть количество строк после каждого шага:
SELECT COUNT(*) FROM orders;
SELECT COUNT(*)
FROM orders
JOIN order_items ON order_items.order_id = orders.id;
SELECT COUNT(*)
FROM orders
JOIN order_items ON order_items.order_id = orders.id
JOIN products ON products.id = order_items.product_id;
Так обычно сразу видно, на каком JOIN начинаются лишние строки.
🔥 Итог простой: перед тем как писать JOIN, всегда держите в голове гранулярность данных. Что у вас является одной строкой: заказ, позиция заказа, клиент? Сначала определяете уровень данных — потом джойните и агрегируете.
➡️ SQL Ready | #практикаversion или updated_at). Pessimistic locking наоборот сразу ставит блокировку (SELECT ... FOR UPDATE) и заставляет другие транзакции ждать.
На картинке — как два подхода ведут себя при одновременном обновлении одной строки: в одном случае получаем conflict, в другом — очередь.
Сохрани, чтобы не потерять!
➡️ SQL Ready | #ресурсWHERE id = ANY(...) находит нужные строки, но порядок входного массива не сохраняет:
SELECT *
FROM users
WHERE id = ANY(ARRAY[42, 7, 99]);
Такой запрос вернёт правильный набор строк, но порядок будет таким, как решит планировщик, а не таким, как пришёл список.
WITH ORDINALITY добавляет каждой строке её позицию во входном наборе:
unnest(ARRAY[42, 7, 99]) WITH ORDINALITY
Дальше это уже обычная таблица, которую можно джойнить, фильтровать и сортировать:
ORDER BY x.ord
В итоге база сама возвращает строки в нужном порядке, без CASE, без ручной сортировки в коде и без лишнего постобработчика.
🔥 WITH ORDINALITY — это простой способ сохранить порядок входных данных в SQL, он хорошо заходит в API и массовые выборки.
➡️ SQL Ready | #советОставляю ссылочку: GitHub 📱➡️ SQL Ready | #репозиторий
FILTER позволяет задать условие прямо для SUM, COUNT, AVG — без вложенных подзапросов и лишнего шума. Код получается чище, короче и проще читается.
Что важно знать:
• FILTER работает внутри агрегата — условие применяется только к нему. • Отлично подходит для отчётных таблиц с множеством условий. • Заменяет CASE WHEN в 90% ситуаций, где раньше казалось без него никак.Поэтому, это инструмент, с которым SQL-запросы становятся короче и понятнее. ➡️ SQL Ready | #гайд
SELECT user_id, email, created_at
FROM users
WHERE user_id IS NULL
OR email IS NULL;
Проверяем дубликаты по уникальному полю и сразу классифицируем их:
SELECT email, COUNT(*) AS cnt,
CASE WHEN COUNT(*)>1 THEN 'Duplicate' ELSE 'Unique' END AS status
FROM users
GROUP BY email;
Ищем аномалии в числовых полях (например, сумма заказа < 0):
SELECT order_id, total_amount
FROM orders
WHERE total_amount < 0;
🔥 Это позволяет отслеживать качество данных, предотвращать ошибки аналитики и готовить отчёты для команды разработки.
➡️ SQL Ready | #практикаUNIQUE в SQL пропускает несколько NULL, потому что NULL не считается равным другому. Из-за этого ограничение часто формально есть, а правило на самом деле не соблюдается:
UNIQUE (telegram_id)
Если колонка опциональная, но по смыслу значение всё равно должно быть уникальным, стандартный UNIQUE даёт дыру в данных.
UNIQUE NULLS NOT DISTINCT (telegram_id)
Эта форма говорит PostgreSQL считать NULL обычным сравнимым значением именно для проверки уникальности.
То есть второй NULL уже не пройдёт, как и дубликат обычного значения.
UNIQUE NULLS NOT DISTINCT (tenant_id, external_id)
Особенно полезно для nullable внешних идентификаторов, one-to-one связей, интеграционных ключей и любых полей, где NULL тоже должен быть единственным допустимым состоянием.
🔥 UNIQUE NULLS NOT DISTINCT закрывает один из источников грязных данных и заменяет триггеры.
➡️ SQL Ready | #совет