This media is not supported in your browser
VIEW IN TELEGRAM
Репозиторий предлагает серию упражнений и заданий на каждый день, которые охватывают ключевые темы: выборки, агрегации, подзапросы, оконные функции и др. Формат один день - одна задача помогает не перегружаться и выстраивать структурированный план обучения. Отлично подходит для практики, подготовки к собеседованиям и укрепления знаний.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥10🤝7❤1
Find + Update в одном проходе!
Найдём строки с невозможными значениями и сразу подготовим их к
Теперь обновим только найденные строки, не дублируя условие в клиенте:
Ссылаемся на выборку из
Попробуйте сами на тестовой таблице:
Запустите
🔥 Экономит время выравнивания таблиц при интеграциях, корректировки классификаторов или миграций и др.
➡️ SQL Ready | #совет
Найдём строки с невозможными значениями и сразу подготовим их к
UPDATE:WITH c AS (SELECT id FROM products WHERE price < 0 LIMIT 3)
CTE c вернёт проблемные id.Теперь обновим только найденные строки, не дублируя условие в клиенте:
UPDATE products SET price = 0
Ссылаемся на выборку из
CTE, чтобы не рассинхронизировать find/update:WHERE id IN (SELECT id FROM c);
Попробуйте сами на тестовой таблице:
CREATE TABLE products(id int PRIMARY KEY, price int);
INSERT INTO products VALUES (1,-10),(2,-5),(3,100);
Запустите
find+update снова и убедитесь, что исправление точечное и атомарное.Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍9🔥8
This media is not supported in your browser
VIEW IN TELEGRAM
Если хочешь учиться через практику, этот сайт отличный инструмент. Здесь ты пишешь запросы прямо в браузере, получаешь мгновенную обратную связь и видишь результат. Подойдёт для закрепления теории, подготовки к собеседованию или реальных задач в работе с бд.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤10🔥9
Сравнение наборов и вычисление пересечения по ключу!
Нужно быстро получить пересечение двух таблиц по ключу? Используйте
Выберите только ключи, чтобы исключить лишние проекции и ускорить анализ наборов:
Проверьте сами на интерактивном примере:
Повторите исходный
🔥 Пригодится, когда нужно сверить итерации, найти общие сущности перед миграциями и тд.
➡️ SQL Ready | #совет
Нужно быстро получить пересечение двух таблиц по ключу? Используйте
JOIN по колонке, которая логически должна совпадать в обоих наборах:JOIN table_b b ON a.id = b.id
Выберите только ключи, чтобы исключить лишние проекции и ускорить анализ наборов:
SELECT a.id
Проверьте сами на интерактивном примере:
CREATE TABLE table_a(id int);
CREATE TABLE table_b(id int);
INSERT INTO table_a VALUES (1),(2),(3);
INSERT INTO table_b VALUES (2),(3),(4);
Повторите исходный
JOIN, вы увидите только 2,3 как пересечение наборов.Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥10❤9
Например,
Skiplist ускоряет поиск в памяти, Hash-индекс даёт доступ за O(1), а B-tree и LSM-дерево оптимизируют работу с диском и записью.На картинке — 8 структур данных, которые стоит держать под рукой, чтобы понимать, как устроены индексы и хранение в БД.
Сохрани, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤8🔥6🤝4
UNION и UNION ALL — когда строки исчезают без ошибок!
Одинаковые
Для логов полезно явно добавлять источник:
Пересечение (
Если хотите увидеть, какие строки пропадут при
🔥
➡️ SQL Ready | #практика
UNION удаляет дубликаты по всем выбранным колонкам, сравнивая строки целиком, поэтому результат может отличаться от ожиданий.SELECT message FROM logs_app
UNION
SELECT message FROM logs_system;
Одинаковые
message схлопнутся в одну строку, даже если это разные события — ошибки не будет.UNION ALL не удаляет строки из результата запросов, поэтому почти всегда работает быстрее: SELECT message FROM logs_app
UNION ALL
SELECT message FROM logs_system;
Для логов полезно явно добавлять источник:
SELECT 'app' AS src, id, message FROM logs_app
UNION ALL
SELECT 'system' AS src, id, message FROM logs_system
ORDER BY src, id;
Пересечение (
INTERSECT) в MySQL не поддерживается, альтернатива:SELECT DISTINCT a.message
FROM logs_app a
WHERE EXISTS (SELECT 1 FROM logs_system s WHERE s.message = a.message)
LIMIT 10;
Если хотите увидеть, какие строки пропадут при
UNION из-за совпадений между таблицами, используйте UNION ALL и проверяйте строки, встречающиеся в обоих источниках:SELECT message, COUNT(*) AS cnt, COUNT(DISTINCT src) AS sources
FROM (
SELECT message, 'app' AS src FROM logs_app
UNION ALL
SELECT message, 'system' AS src FROM logs_system
) t
GROUP BY message
HAVING sources > 1;
UNION — когда нужна дедупликация, UNION ALL — когда важна каждая строка и производительность.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥9❤7
В этой статье:
• Автор показывает, как хранить и группировать SQL-запросы в одном .sql-файле по сущностям;
• Рассказывается, как использовать go:embed для встраивания этих файлов в бинарник и загружать запросы по имени;
• Представлен парсер, который разбирает .sql с именованными секциями;
• Показаны преимущества подхода: подсветка SQL в IDE, чистый Go-код и др.🔊 Продолжайте читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥7🤝7
Как выполнять сложные data-миграции, не ломая UNIQUE-ограничения?
Иногда нужно массово менять данные, временно нарушая
Включаем отложенную проверку конкретного ограничения, оно проверится только при
Теперь можно выполнять
Фиксация происходит один раз, если финальное состояние валидно, транзакция коммитится:
Если уникальность нарушена в конце будет
🔥 Отложенные ограничения позволяют безопасно менять данные внутри транзакции, сохраняя целостность и контроль без временного снятия
➡️ SQL Ready | #совет
Иногда нужно массово менять данные, временно нарушая
UNIQUE, но итоговое состояние корректно:BEGIN;
Включаем отложенную проверку конкретного ограничения, оно проверится только при
COMMIT:SET CONSTRAINTS users_email_uniq DEFERRED;
Теперь можно выполнять
UPDATE/INSERT, даже если в процессе появляются дубликаты:UPDATE users
SET email = lower(email);
Фиксация происходит один раз, если финальное состояние валидно, транзакция коммитится:
COMMIT;
Если уникальность нарушена в конце будет
ROLLBACK, без частичных изменений.UNIQUE.Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍8🔥7
This media is not supported in your browser
VIEW IN TELEGRAM
Материал построен вокруг реальных примеров и практики: от базовых SELECT, JOIN и агрегатов до сложных подзапросов и аналитических функций. Пояснения идут шаг за шагом, с визуальными примерами и задачами, которые помогают сразу закрепить навыки на практике.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍7🤝6❤1
Оконные фреймы (ROWS и RANGE) — управление областью расчёта!
В оконных функциях важны не только
Таблица операций:
Накопительная сумма по пользователю:
При наличии
Если значения
Среднее по последним 3 операциям:
Сумма за последние 7 дней (пример для PostgreSQL):
🔥 Важно помнить:
➡️ SQL Ready | #практика
В оконных функциях важны не только
PARTITION BY и ORDER BY, но и то, какие строки попадают в окно вычисления. За это отвечают оконные фреймы — ROWS и RANGE.Таблица операций:
transactions(id, user_id, amount, created_at)
Накопительная сумма по пользователю:
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY created_at
)
При наличии
ORDER BY и отсутствии явного фрейма в большинстве СУБД используется RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.Если значения
created_at совпадают, сумма считается сразу по группе строк (peers).Среднее по последним 3 операциям:
AVG(amount) OVER (
PARTITION BY user_id
ORDER BY created_at, id
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
ROWS формирует окно по количеству строк. Детерминированный ORDER BY необходим для воспроизводимого результата.Сумма за последние 7 дней (пример для PostgreSQL):
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY created_at
RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW
)
RANGE формирует окно по значениям ORDER BY. Поддержка и синтаксис интервалов зависят от СУБД; часто допускается только одно выражение в ORDER BY.ROWS — предсказуем по количеству строк, RANGE — удобен для временных интервалов и peer-групп, неявный фрейм может менять результат вычисленийPlease open Telegram to view this post
VIEW IN TELEGRAM
❤11👍10🔥8
Согласованное чтение данных внутри одной транзакции!
Иногда несколько
В PostgreSQL это фиксирует
Все последующие
Это гарантирует согласованность результатов между запросами без блокировки пишущих транзакций:
🔥 После
➡️ SQL Ready | #совет
Иногда несколько
SELECT должны работать с одной и той же версией данных, даже если параллельно идут изменения.BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
В PostgreSQL это фиксирует
MVCC snapshot в момент первого statement внутри транзакции:SELECT COUNT(*) FROM orders;
Все последующие
SELECT читают один и тот же snapshot и не видят новые COMMIT из других сессий, при этом собственные изменения транзакции видны:SELECT SUM(amount) FROM orders;
Это гарантирует согласованность результатов между запросами без блокировки пишущих транзакций:
COMMIT;
COMMIT snapshot освобождается, транзакция завершается.Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🔥9👍8
Например,
1NF требует атомарных значений, 2NF убирает частичные зависимости, а 3NF избавляет от транзитивных зависимостей.На картинке — основные нормальные формы, которые полезны при проектировании SQL-баз данных.
Сохрани, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍9🤝7❤1
EXPLAIN — узнаём, как СУБД реально выполняет ваш запрос!
Команда
Допустим, у нас есть запрос:
Запускаем
Если видим
Чтобы ускорить выполнение, создаём индекс:
🔥 Теперь при повторном
➡️ SQL Ready | #практика
Команда
EXPLAIN показывает, что делает база данных под капотом при выполнении SQL-запроса. Это помогает найти узкие места и понять, почему запрос может работать медленно.Допустим, у нас есть запрос:
SELECT * FROM books WHERE author = 'Толстой';
Запускаем
EXPLAIN, чтобы посмотреть план выполнения:EXPLAIN SELECT * FROM books WHERE author = 'Толстой';
Если видим
Table Scan или Seq Scan — это означает, что происходит полный просмотр таблицы. Такой способ может быть медленным, особенно при большом объёме данных.Чтобы ускорить выполнение, создаём индекс:
CREATE INDEX idx_author ON books(author);
EXPLAIN запрос может использовать Index Scan, что значительно быстрее.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍10❤8
This media is not supported in your browser
VIEW IN TELEGRAM
Вводишь любую команду в терминале, и он по частям объясняет, что делает каждая часть. Не просто man-ка, а понятный синтакс-анализ.
Особенно кайф для тех, кто работает в
Linux/DevOps/CI среде и хочет разбираться, а не наугад копипастить из StackOverflow.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥9🤝9
Когда в запросе нужны 2-3 конкретных поля, база может отдать их прямо из индекса, не трогая таблицу. Это особенно важно для тяжёлых таблиц, где каждый лишний lookup - потеря времени.
Сегодня в гайде:
• Как запрос выполняется только из индекса;
• Как убедиться, что таблица не читается (Heap Fetches: 0 в плане);
• Как проектировать индексы, чтобы покрывать SELECT полностью.
Покрывающий индекс устраняет table lookup, снижает I/O и делает чтение стабильным при росте данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤8👍6🤝1
Например,
INNER JOIN возвращает только совпадающие строки из двух таблиц, а LEFT JOIN позволяет получить все записи из основной таблицы, даже если связанной записи нет.На картинке — 4 самых используемых типа SQL JOIN, которые постоянно встречаются в рабочих запросах.
Сохрани, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍9🔥7
IS NOT DISTINCT FROM - равенство без NULL!
Обычное сравнение через
Эта проверка никогда не вернёт строки с NULL, даже если логически они равны:
Работает и для составных сравнений, без
🔥
➡️ SQL Ready | #совет
Обычное сравнение через
= ломается, если возможен NULL:SELECT *
FROM users
WHERE email = 'admin@example.com';
Эта проверка никогда не вернёт строки с NULL, даже если логически они равны:
SELECT *
FROM users
WHERE email IS NOT DISTINCT FROM NULL;
IS NOT DISTINCT FROM считает NULL = NULL и работает как настоящее равенство:sql
SELECT *
FROM users
WHERE (email, phone)
IS NOT DISTINCT FROM ('a@b.com', NULL);
Работает и для составных сравнений, без
OR … IS NULL.IS NOT DISTINCT FROM - способ сравнивать значения, когда NULL допустимое состояние, а не исключение.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤8🔥7👎1