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
✍️ 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
❤️ Мега интересную статью нашёл на Хабре: «DOOMQL: DOOM-подобный многопользовательский шутер на чистом SQL»!

В этой статье:
• Показано, как реализовать полноценную игру, от хранения состояния до рендеринга 3D-сцены — средствами одной лишь базы данных;
• Разобрана архитектура, игровой цикл на транзакциях и многопользовательская синхронизация через SQL;
• На реальном проекте демонстрируются неожиданные возможности СУБД далеко за пределами типичных CRUD-задач.


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


➡️ SQL Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
15🔥10🤝8
🔥107👍4🤝3👎1
Что же выведет консоль?
Anonymous Quiz
24%
A
27%
B
30%
C
19%
D
🔥138👍7🤝3
📂 Напоминалка: как выполняется SQL-запрос в базе данных!

Например, когда отправляешь SELECT, UPDATE или другой SQL, СУБД сначала обрабатывает его внутренне, а уже потом выполняет.

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

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

➡️ SQL Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥7👍5
Анти-JOIN — как корректно выбирать строки без связанных записей!

Частая задача в SQL — найти строки, для которых отсутствуют связанные записи в другой таблице. Это классический anti-join. Например, нужно получить клиентов, которые ни разу не сделали заказ.

Таблицы:
customers(id, name)
orders(id, customer_id, created_at)


LEFT JOIN + IS NULL:
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
WHERE o.id IS NULL;


LEFT JOIN возвращает всех клиентов. Если совпадений нет, поля из orders становятся NULL, и фильтр оставляет только клиентов без заказов.

Проверять нужно гарантированно NOT NULL колонку правой таблицы (обычно PK, например o.id), иначе возможны логические ошибки.

NOT EXISTS (предпочтительно):
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
);


Запрос напрямую выражает отсутствие строк. В простом случае он эквивалентен LEFT JOIN, но лучше отражает намерение, устойчив к NULL в подзапросе и часто даёт более предсказуемый план при усложнении условий.

Почему не NOT IN:
SELECT c.id, c.name
FROM customers c
WHERE c.id NOT IN (
SELECT customer_id
FROM orders
);


Если подзапрос возвращает хотя бы один NULL, результат может стать пустым из-за трёхзначной логики SQL. Использовать этот вариант безопасно только при гарантированном NOT NULL в orders.customer_id.

Нюанс с условиями в JOIN:
SELECT c.id
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
AND o.created_at >= DATE '2026-01-01'
WHERE o.id IS NULL;


Этот запрос ищет клиентов без заказов после указанной даты.

Если требуется найти клиентов вообще без заказов, добавлять условия в JOIN нельзя — это меняет бизнес-смысл. В таком случае корректнее использовать NOT EXISTS.

🔥 Минимально необходим индекс orders(customer_id). При частой фильтрации по дате логичен составной индекс (customer_id, created_at).

➡️ SQL Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54🔥4