SQL Ready | Базы Данных
15.5K subscribers
1.2K photos
65 videos
2 files
575 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
👍 TutorialsPoint — сайт с теорий и практикой в одном месте!

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

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

➡️ SQL Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍9🔥7🤝2
Проверка наличия связанных данных!

Когда нужно проверить существование связанных строк, обычный JOIN часто увеличивает результат или заставляет делать DISTINCT, что бьёт по производительности:
SELECT *
FROM orders o
WHERE EXISTS (
SELECT 1 FROM payments p
WHERE p.order_id = o.id
);


EXISTS останавливается на первой найденной строке и не создаёт дубликатов, поэтому обычно работает быстрее и предсказуемее:
SELECT *
FROM orders o
WHERE NOT EXISTS (
SELECT 1 FROM payments p
WHERE p.order_id = o.id
);


NOT EXISTS - наиболее корректный способ найти записи без соответствующих связанных данных.

В отличие от NOT IN он корректнее работает при наличии NULL:
SELECT *
FROM orders o
LEFT JOIN payments p ON p.order_id = o.id
WHERE p.order_id IS NULL;


🔥 LEFT JOIN + IS NULL делает то же самое логически, но чаще требует больше работы оптимизатора и может уступать по производительности на больших объёмах.

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍11🤝8
💡 Отличную статью нашёл на Хабре: «Демобаза 2.0 для PostgreSQL»!

В этой статье:
• Показано, как устроена учебная база, приближенная к реальным продакшен-сценариям с миллионами записей;
• Разобрано, как генерируются правдоподобные данные через имитацию работы системы, включая бронирования и жизненный цикл событий;
• Объясняется, какие задачи по SQL, аналитике и производительности можно отрабатывать на такой базе.


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


➡️ SQL Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍9🤝81
TRUNC(date) — как правильно обрезать дату в Oracle без потери индекса!

В Oracle тип DATE хранит дату и время одновременно. Частая задача — сравнить только по дате, игнорируя время. Многие используют TRUNC(date), но это может сильно ухудшить производительность.

Представим таблицу:
orders(id, created_at DATE)


Нужно выбрать заказы за 18 февраля 2026.

Интуитивный вариант:
SELECT *
FROM orders
WHERE TRUNC(created_at) = DATE '2026-02-18';


Логически верно, но есть проблема.

Функция применяется к колонке — поэтому обычный индекс по created_at в основном не используется, и Oracle вынужден вычислять TRUNC для множества строк, что часто приводит к полному сканированию.

Правильный способ — диапазон по дате:
SELECT *
FROM orders
WHERE created_at >= DATE '2026-02-18'
AND created_at < DATE '2026-02-19';


Теперь условие индекс-дружелюбное (sargable) — оптимизатор может использовать обычный индекс по created_at.

Этот подход корректно работает независимо от времени в поле.

TRUNC(date) полезен в SELECT или GROUP BY, когда фильтрация по индексу не критична:
SELECT
TRUNC(created_at) AS day,
COUNT(*) AS orders_count
FROM orders
GROUP BY TRUNC(created_at)
ORDER BY day;


Если всё же нужно часто фильтровать по TRUNC(created_at), можно создать функциональный индекс:
CREATE INDEX idx_orders_created_day
ON orders (TRUNC(created_at));


После этого запрос с TRUNC сможет использовать индекс.

Функция TRUNC умеет обрезать дату до разных уровней:
SELECT
TRUNC(SYSDATE) AS day,
TRUNC(SYSDATE, 'MM') AS month_start,
TRUNC(SYSDATE, 'YYYY') AS year_start
FROM dual;


Поддерживаются форматы: DD (день), MM (месяц), YYYY (год), IW (ISO-неделя) и др.

DATE хранит дату со временем, поэтому = DATE '2026-02-18' не находит все записи за день; функции над колонками мешают индексам.

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

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍9🤝83
This media is not supported in your browser
VIEW IN TELEGRAM
FlowchartAI — это бесплатный AI-генератор блок-схем, который из текста или кода автоматически строит диаграмму. Он анализирует твой ввод (описание процесса/алгоритма или код) и превращает его в визуальную блок-схему, которую можно смотреть прямо в браузере без регистрации.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍138🤝8👎1
👍11🔥8🤝6
Что же выведет консоль?
Anonymous Quiz
20%
A
13%
B
27%
C
39%
D
👍14🔥9🤝91
This media is not supported in your browser
VIEW IN TELEGRAM
💡 SQL Fiddle — онлайн платформа для тестирования SQL без установки БД!

Сервис позволяет писать, запускать и проверять SQL-запросы прямо в браузере. Можно создать схему базы, заполнить тестовыми данными и сразу увидеть результат выполнения, идеально для экспериментов, обучения и разбора задач. Поддерживает разные СУБД (MySQL, PostgreSQL, Oracle, SQL Server и др.), поэтому удобно сравнивать поведение запросов.

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

➡️ SQL Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍1110
Вычисление временных интервалов между датами!

PostgreSQL умеет возвращать полноценный интервал одной операцией:
now() - created_at


Если нужно получить возраст записи в читаемом виде (годы-месяцы-дни), есть функция age(), которая учитывает календарь, а не просто секунды:
SELECT age(now(), created_at)
FROM orders;


А когда требуется число дней или часов для аналитики, интервал можно сразу привести к нужной единице:
EXTRACT(EPOCH FROM now() - created_at) / 3600


🔥 Полезно для TTL-логики, SLA-метрик, мониторинга задержек и любых задач, где время жизни записи, является ключевым параметром.

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍9🔥9
📂 Напоминалка по SQL — базовые команды и порядок выполнения запроса!

Например, SELECT отвечает за выборку данных, FROM — за указание источника (таблицы), а WHERE позволяет отфильтровать строки по условию.

На картинке — основные операторы SQL, типы JOIN’ов и правильный порядок выполнения запроса внутри СУБД.

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1910🔥9
🖥 Объединяем пересекающиеся интервалы автоматически!

В реальных данных интервалы часто перекрываются или соприкасаются, из-за чего сложно понять фактические периоды непрерывной активности или занятости.

Сегодня в задаче:
Определим, насколько далеко тянется текущая занятость, отслеживая максимальный конец интервалов;

Найдём точки разрыва, где начинается новый независимый блок времени;

Объединим пересечения в итоговые непрерывные диапазоны.


Этот приём используют для анализа сессий, расписаний, бронирований и любых временных событий, где важно видеть реальные интервалы.

➡️ SQL Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥9🤝81
This media is not supported in your browser
VIEW IN TELEGRAM
✍️ Bilabon — задачи и теория по MySQL!

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

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


➡️ SQL Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍8🤝63
SYSDATE в условиях — почему = SYSDATE почти никогда не то, что нужно!

В Oracle SYSDATE возвращает текущие дату и время с точностью до секунды. Частая ошибка — пытаться выбрать записи «за сегодня» через прямое сравнение.

Представим таблицу:
orders(id, created_at DATE)


Интуитивный вариант:
SELECT *
FROM orders
WHERE created_at = SYSDATE;


Логически кажется правильным — взять записи за текущий день. Но условие почти никогда не выполнится.

Тип DATE в Oracle хранит и дату, и время (до секунды). Чтобы совпадение произошло, created_at должен быть ровно равен текущему моменту до секунды. На практике такой запрос почти всегда возвращает пустой результат.

Попытка исправить через TRUNC:
SELECT *
FROM orders
WHERE TRUNC(created_at) = TRUNC(SYSDATE);


Работает корректно, но есть нюанс — функция применяется к колонке, поэтому обычный индекс по created_at не используется (если только нет function-based index на TRUNC(created_at)).

Правильный способ — диапазон по дате:
SELECT *
FROM orders
WHERE created_at >= TRUNC(SYSDATE)
  AND created_at <  TRUNC(SYSDATE) + 1;


Такое условие индекс-дружелюбное (sargable), и оптимизатор может использовать индекс. Запрос выбирает все записи за текущие сутки независимо от времени (по часовому поясу сессии/сервера БД).

Аналогично можно искать за любой день:
WHERE created_at >= DATE '2026-02-18'
  AND created_at <  DATE '2026-02-19'


Поскольку DATE хранит время, прямое равенство по дате почти никогда не подходит для выборки «за день».

🔥 Для выборки за день используйте полуоткрытый диапазон, а не сравнение с SYSDATE.

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍129🤝8
Проверка совпадений сразу по нескольким полям одной операцией!

Когда нужно сравнить строки по составному ключу, многие пишут условия с AND, которые хуже читаются и сложнее поддерживаются:
u.email = b.email AND u.phone = b.phone


SQL умеет сравнивать кортежи целиком (row value), поэтому несколько колонок можно проверить одним выражением:
(email, phone)


Поддержка зависит от СУБД. Учитывайте поведение NULL и наличие составных индексов, оптимизация не всегда идентична AND.

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

➡️ SQL Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🤝98🔥1
Дедупликация с приоритетом, оставляем лучшую строку!

Когда есть дубликаты по ключу (например, email), нужно сохранить запись с максимальным приоритетом — подтверждённую или самую новую.

Таблица: users(id, email, is_verified, created_at)

Сначала можно увидеть, какая строка будет считаться главной. Нумеруем строки внутри каждого email по приоритету:
SELECT id, email,
       ROW_NUMBER() OVER (
         PARTITION BY email
         ORDER BY is_verified DESC, created_at DESC
       ) rn
FROM users;


Оконная функция делит строки по email и присваивает номер согласно приоритету, где подтверждённые и более новые записи идут первыми.

Оставим только одну запись на email — ту, у которой rn = 1:
SELECT *
FROM (
  SELECT *,
         ROW_NUMBER() OVER (
           PARTITION BY email
           ORDER BY is_verified DESC, created_at DESC
         ) rn
  FROM users
) t
WHERE rn = 1;


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

В PostgreSQL можно сделать то же самое короче:
SELECT DISTINCT ON (email)
       id, email, is_verified, created_at
FROM users
ORDER BY email, is_verified DESC, created_at DESC;


Здесь ORDER BY фактически задаёт правило выбора победителя внутри каждой группы. СУБД оставит одну строку на email согласно приоритету сортировки.

🔥 Такой приём используют при очистке импортов, объединении источников данных и выборе канонической записи пользователя.

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1410🔥8
🖥 Oracle: работа с датой и временем!

Основные функции и приёмы работы с календарными значениями в Oracle: получение текущих даты и времени на стороне БД, вычисление интервалов, смещение по месяцам, усечение до нужной гранулярности, извлечение компонентов даты, а также корректное преобразование строк в DATE и TIMESTAMP. Полезно для отчётов, аналитики, планирования, ETL-процессов и любой логики, связанной с датами и временем.

➡️ SQL Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍10🤝72