SQL Ready | Базы Данных
15.4K subscribers
1.2K photos
65 videos
2 files
577 links
Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Автор: @energy_it

РКН: https://clck.ru/3QREBc

Реклама на бирже: https://telega.in/c/sql_ready
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
😎 SQL Style Guide — супер полезный репозиторий для освоения языка!

Практичный ресурс по написанию SQL: как оформлять SELECT, JOIN, CTE, подзапросы и имена таблиц, чтобы запросы были понятными, поддерживаемыми и удобными для работы в команде. Подходит для любых СУБД и реально упрощает работу и учебу.

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


➡️ SQL Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍97
FILTER в агрегатных функциях PostgreSQL!

В аналитических запросах часто нужно посчитать несколько показателей из одной таблицы. В PostgreSQL для этого есть 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 | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝15👍107🔥3
📂 Напоминалка по масштабированию баз данных!

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

На картинке — 10 техник масштабирования БД, которые стоит держать под рукой при работе с высокими нагрузками.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝11👍9🔥9
Условный UPSERT: как не обновлять строки без изменений?

Обычный 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 | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥158👍8
👍13🔥7🤝7😁1
NULL и NOT IN — тонкость SQL, приводящая к логическим ошибкам!

При использовании 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 | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍148🤝7
🖥 Ищем клиентов без единого заказа — полезный приём для выявления неактивных пользователей и повышения конверсии!

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

Основные моменты:
• LEFT JOIN — соединяем таблицы, чтобы сохранить всех клиентов, даже тех, у кого нет заказов.

• WHERE o,id IS NULL — отбираем только тех, для кого заказов не найдено.

• SELECT — выводим имя, email и дату регистрации.


SQL Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20🤝10👍81
📂 Напоминалка по SQL Injection (SQLi)!

Например, простая инъекция вроде OR 1=1 может вернуть все данные из таблицы, а blind SQLi позволяет вытаскивать информацию даже тогда, когда приложение не показывает ошибки и результаты запросов.

На картинке — основные типы SQL-инъекций, которые важно знать при работе с базами данных и backend-логикой.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍7🤝7🔥1
Как понять, что PostgreSQL работает на устаревшей статистике?

PostgreSQL хранит информацию о последнем сборе статистики:
SELECT relname,
last_analyze,
last_autoanalyze,
n_live_tup
FROM pg_stat_user_tables;


last_analyze — когда статистика обновлялась вручную,
last_autoanalyze — когда это делал autovacuum.

Чтобы быстро найти проблемные таблицы, отсортируем по размеру:
SELECT relname,
n_live_tup,
last_analyze,
last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;


Большая таблица + старый last_analyze — оптимизатор работает вслепую.

В таком случае достаточно обновить статистику:
ANALYZE;


Или точечно, для одной таблицы:
ANALYZE orders;


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

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥87
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ StrataScratch — вопросы с собеседований!

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

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1210🔥8
☕️ На Хабре вышла подробная статья про автоматизацию развертывания PostgreSQL-кластеров в изолированной инфраструктуре.

В этой статье:
• Показан реальный подход к автоматическому развёртыванию PostgreSQL в закрытом контуре;
• Разбирается поддержка нескольких ОС, версий СУБД и схем отказоустойчивости;
• Описана автоматическая проверка соответствия требованиям архитектуры;
• Приведён практический кейс внедрения, рассчитанный на эксплуатацию в крупных корпоративных системах.

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


➡️ SQL Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍8🤝61
👍149🔥8👎2
Что же выведет консоль?
Anonymous Quiz
21%
A
39%
B
9%
C
31%
D
👍119🔥9👎1
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ Postgrespro — полная и актуальная документация по PostgreSQL!

SQL-синтаксис, индексы, транзакции, планировщик запросов, репликация, расширения и внутренняя архитектура. Здесь подробно описано не только как писать запросы, но и как база данных работает. Полезно, если используешь Postgres в продакшене или хочешь глубже разобраться в производительности.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥11🤝7
Оконные функции ROW_NUMBER() в SQL — нумерация строк для аналитики!

ROW_NUMBER() присваивает уникальный порядковый номер строкам внутри логического окна. Данные не объединяются в группы, строки остаются как есть — это ключевое отличие от GROUP BY.

Таблица:
payments(id, user_id, amount, created_at)


Нумеруем платежи каждого пользователя. Окно создаётся по user_id, а нумерация идёт по дате от старых к новым:
SELECT id, user_id, amount,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC) AS rn
FROM payments;


PARTITION BY разбивает данные на сегменты (в данном случае — по пользователю). ORDER BY внутри OVER() задаёт, в каком порядке будут присваиваться номера.

Чтобы найти последний платёж каждого пользователя, меняем порядок сортировки на DESC. Самая свежая запись получит номер 1 в своём окне:
WITH t AS (
SELECT id, user_id, amount,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
FROM payments
)
SELECT * FROM t WHERE rn = 1;


Здесь используем CTE (WITH), чтобы сначала пронумеровать строки, а затем отфильтровать только нужный номер.

Следующий пример — логины пользователей:
auth_logs(id, user_id, ip, login_at)


Ищем первый вход каждого пользователя с каждого IP:
WITH t AS (
SELECT id, user_id, ip,
ROW_NUMBER() OVER (PARTITION BY user_id, ip ORDER BY login_at ASC) AS rn
FROM auth_logs
)
SELECT * FROM t WHERE rn = 1;


🔥 ROW_NUMBER() подходит, когда нужен номер строки в сегменте, важно выбрать первую/последнюю запись по логике сортировки,требуется топ-N по категориям или пользователям.

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥168👍6🤝1
🔥13👍7🤝7