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

Автор: @energy_c

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

Реклама на бирже: https://telega.in/c/sql_ready
Download Telegram
Временные таблицы: различия между TEMP, CTE и материализацией данных!

В SQL существует несколько способов работать с промежуточными результатами. Основные варианты — временные таблицы, CTE через WITH и обычные подзапросы. Выбор между ними влияет на читаемость запроса, возможность повторного использования данных и работу оптимизатора.

Временная таблица создаётся внутри текущей сессии базы данных и существует до её завершения или до явного удаления. Она подходит для многоэтапной обработки данных, когда результат нужно использовать в нескольких следующих запросах.
CREATE TEMP TABLE monthly_sales AS
SELECT
customer_id,
SUM(amount) AS total_amount
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY customer_id;


После создания временная таблица становится отдельным объектом базы данных. К ней можно обращаться как к обычной таблице, создавать индексы и выполнять дополнительные операции.
SELECT *
FROM monthly_sales
WHERE total_amount > 10000;


Временные таблицы особенно полезны при сложных процессах обработки данных, где нужно разделить вычисления на несколько этапов и повторно использовать промежуточный результат.
CREATE INDEX idx_monthly_sales_customer_id
ON monthly_sales(customer_id);


CTE (Common Table Expression) создаётся с помощью конструкции WITH и существует только во время выполнения одного SQL-запроса. Он помогает сделать сложную логику более читаемой и структурированной.
WITH monthly_sales AS (
SELECT
customer_id,
SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
)
SELECT *
FROM monthly_sales
WHERE total_amount > 10000;


В PostgreSQL начиная с версии 12 CTE может быть автоматически встроен оптимизатором в основной запрос. Это называется CTE inlining. В таком случае отдельное промежуточное хранилище данных не создаётся.
WITH active_users AS MATERIALIZED (
SELECT *
FROM users
WHERE status = 'active'
)
SELECT *
FROM active_users;


Основное отличие MATERIALIZED заключается в том, что PostgreSQL принудительно сохраняет результат CTE перед дальнейшей обработкой. Это может быть полезно, если один и тот же результат используется несколько раз или нужно избежать повторного выполнения тяжёлого вычисления.
WITH user_stats AS MATERIALIZED (
SELECT
user_id,
COUNT(*) AS orders_count
FROM orders
GROUP BY user_id
)
SELECT
a.user_id,
a.orders_count
FROM user_stats a
JOIN user_stats b
ON a.user_id = b.user_id;


Однако использование CTE не всегда означает материализацию. PostgreSQL самостоятельно выбирает оптимальный способ выполнения запроса, если не указано MATERIALIZED или NOT MATERIALIZED.
WITH user_stats AS NOT MATERIALIZED (
SELECT
user_id,
COUNT(*) AS orders_count
FROM orders
GROUP BY user_id
)
SELECT *
FROM user_stats;


Если промежуточный результат большой и используется несколько раз в рамках сложного процесса, временная таблица часто подходит лучше. Она позволяет создать индексы, выполнять дополнительные запросы и управлять этапами обработки отдельно.
CREATE TEMP TABLE user_stats AS
SELECT
user_id,
COUNT(*) AS orders_count
FROM orders
GROUP BY user_id;

CREATE INDEX idx_user_stats_user_id
ON user_stats(user_id);

ANALYZE user_stats;


Команда ANALYZE после заполнения временной таблицы помогает PostgreSQL получить актуальную статистику и выбрать более эффективный план выполнения запроса.

Обычный подзапрос существует только внутри конкретного SQL-выражения. Он подходит для локальных вычислений, когда результат нужен только в одном месте и не требуется повторное использование.
SELECT *
FROM (
SELECT
user_id,
COUNT(*) AS orders_count
FROM orders
GROUP BY user_id
) s
WHERE orders_count > 50;


🔥 Выбор подходящего варианта зависит от задачи. CTE обычно используют для повышения читаемости и разделения сложной логики внутри одного запроса. Временные таблицы подходят для многошаговой обработки, больших промежуточных результатов и случаев, когда нужны индексы. Подзапросы удобны для простых локальных вычислений внутри одного SQL-выражения.

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍9🔥7
🖥 Oracle — преобразование и проверка данных!

Шпаргалка по преобразованию и проверке данных в Oracle: работа со строками, числами, датами, временем и Unicode. Используется для явного преобразования типов, форматирования значений, проверки корректности входных данных и обработки символьных данных.

➡️ SQL Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥128👍7
This media is not supported in your browser
VIEW IN TELEGRAM
👨‍💻 Koddo — сайт с теорией и практикой для обучения!

Платформа для изучения SQL через решение реальных задач прямо в браузере. На практике разбираются выборки и фильтрация, GROUP BY и HAVING, JOIN, работа с датами, подзапросы, CTE и оконные функции. Решения автоматически проверяются, а AI-ассистент может дать подсказку, не раскрывая готовый ответ.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
12🔥11🤝6
Работайте с периодами как с одним значением!

Когда у записи есть start_at и end_at, проверки пересечений быстро превращаются в набор сравнений. В PostgreSQL для этого есть range types: например, tstzrange для диапазона timestamptz.

Вместо:
WHERE start_at < :end_at
AND end_at > :start_at


можно явно работать с диапазонами:
WHERE tstzrange(start_at, end_at, '[)')
&& tstzrange(:start_at, :end_at, '[)')


Оператор && означает «диапазоны пересекаются». [) задаёт полуинтервал: начало включено, конец исключён, поэтому встреча до 12:00 и следующая с 12:00 не считаются пересекающимися.

Но интереснее то, что PostgreSQL умеет проверять диапазоны и другими операторами:
period @> now()       -- содержит момент времени
period && :period -- пересекается
period <@ :period -- находится внутри


Если такие проверки выполняются постоянно, диапазон можно хранить непосредственно в таблице и индексировать GiST:
CREATE INDEX bookings_period_idx
ON bookings USING gist (period);


И самое полезное: правило «для одной комнаты интервалы не должны пересекаться» можно перенести из приложения непосредственно в БД:
CREATE EXTENSION IF NOT EXISTS btree_gist;

ALTER TABLE bookings
ADD CONSTRAINT bookings_no_overlap
EXCLUDE USING gist (
room_id WITH =,
period WITH &&
);


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

🔥 Range types превращают интервалы времени из пары колонок и ручной логики в полноценный тип данных: его можно сравнивать, индексировать и даже запретить пересечения на уровне констрейнта.

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝14👍6🔥42
📂 SQL в одной шпаргалке!

Например, SELECT, WHERE и ORDER BY отвечают за выборку, фильтрацию и сортировку данных, JOIN связывает таблицы, а GROUP BY, агрегатные и оконные функции помогают анализировать результаты запросов.

На картинке — структурированная карта SQL: от базовых запросов и объединения таблиц до CTE, подзапросов, DDL/DML/DCL/TCL, транзакций и ограничений целостности данных.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥157👍6
This media is not supported in your browser
VIEW IN TELEGRAM
👨‍💻 Junior Database — база вопросов и ответов по SQL и базам данных!

В репозитории собраны 27 тем, которые часто встречаются при изучении баз данных и подготовке к техническим собеседованиям: транзакции и ACID, нормализация и денормализация, первичные и внешние ключи, JOIN, GROUP BY и HAVING, индексы, миграции, хранимые процедуры и триггеры. Также затрагиваются оптимизация запросов, партицирование, репликация, шардинг и различия между SQL и NoSQL.

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

➡️ SQL Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍9🔥8
🖥 PostgreSQL — блокировки строк и конкурентный доступ!

Шпаргалка по механизмам синхронизации параллельных транзакций в PostgreSQL: защита строк от конкурентных изменений и удаления, управление ожиданием и пропуском занятых строк, явная блокировка таблиц и диагностика ожидающих блокировок. Помогает контролировать конкурентный доступ и корректно реализовывать транзакционные сценарии.

➡️ SQL Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍10🔥8
📂 Шпаргалка по нормализации баз данных в MySQL!

Например, 1NF требует атомарных значений, 2NF избавляет от частичных зависимостей, а 3NF — от транзитивных. Для более сложных схем пригодятся BCNF и 4NF.

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

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥159🤝7👎1
❤️ Интересная статья на Хабре: «Что такое RAGFlow и с чем его едят»!

В этой статье:
• Разберётесь, как RAGFlow помогает LLM работать с внутренними документами и снижать количество галлюцинаций;
• Узнаете, чем RAGFlow отличается от классического RAG и как он обрабатывает PDF, таблицы, схемы и сканы;
• Посмотрите, как развернуть RAGFlow и использовать его для баз знаний, техподдержки и аналитики.

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


➡️ SQL Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍6🤝5
🔥13🤝6👍4
UNIQUE и NULL в PostgreSQL 15!

До PostgreSQL 15 уникальные ограничения считали NULL разными значениями. Это означало, что таблица спокойно принимала сколько угодно строк с NULL, даже если на колонке стоял UNIQUE.
CREATE TABLE users (
email text UNIQUE
);

INSERT INTO users VALUES (NULL);
INSERT INTO users VALUES (NULL);


Обе вставки выполнятся успешно.

Если NULL тоже должен быть уникальным, приходилось придумывать обходные пути. Кто-то делал частичные индексы, кто-то использовал COALESCE(), кто-то заводил отдельные флаги.
CREATE TABLE users (
email text,
CONSTRAINT users_email_key
UNIQUE NULLS NOT DISTINCT (email)
);

INSERT INTO users VALUES (NULL);
INSERT INTO users VALUES (NULL);


Вторая вставка уже завершится ошибкой. Для ограничения NULL считается таким же значением, как и любой другой ключ.
CREATE TABLE users (
tenant_id int,
email text,
CONSTRAINT uq_user
UNIQUE NULLS NOT DISTINCT (tenant_id, email)
);


Полезно, когда NULL — это полноценное значение предметной области, а не просто "неизвестно".

🔥 Небольшая возможность PostgreSQL 15, которая позволяет удалить сразу несколько старых костылей вокруг UNIQUE.

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝12👍98
This media is not supported in your browser
VIEW IN TELEGRAM
🤔 SQL Lab — интерактивная платформа для изучения и практики SQL!

Сайт для тех, кто хочет освоить SQL через работу с запросами. Код пишется прямо в браузере: выполняете запрос, сразу видите результат и получаете автоматическую проверку решения. Обучение построено от базовых SELECT и ORDER BY до JOIN, подзапросов, транзакций, индексов, оптимизации запросов и PostgreSQL. Есть структурированные курсы с теорией и практикой.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍6🔥4