В этой задаче напишем SQL-запрос, который поможет вычислить среднее время сессии для пользователей на разных устройствах за последние 30 дней.
Что делаем:
• Фильтруем сессии по времени и устройствам.
• Считаем длительность каждой сессии.
• Группируем и находим среднее время по типам устройств.
Такой анализ помогает понять, в каких моментах сфокусироваться на улучшении UX и маркетинговых кампаниях.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍10❤8🤝1
Например,
LEFT JOIN позволяет получить все строки из левой таблицы, даже если соответствующих записей в правой таблице нет, а FULL OUTER JOIN возвращает все строки из обеих таблиц, заполняя отсутствующие значения NULL.На изображении показаны 4 основных типа SQL JOIN, которые чаще всего используются при объединении данных из нескольких таблиц.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥10🤝8❤3
Атомарное перемещение данных между таблицами!
Иногда нужно архивировать старые данные: удалить их из основной таблицы и одновременно сохранить в архиве. Многие делают это двумя запросами (
В итоге строки удаляются и архивируются одним атомарным запросом, без повторного чтения таблицы.
🔥 Полезный паттерн для архивирования, миграций, дедупликации и batch-операций над большими таблицами.
➡️ SQL Ready | #совет
Иногда нужно архивировать старые данные: удалить их из основной таблицы и одновременно сохранить в архиве. Многие делают это двумя запросами (
INSERT => DELETE):DELETE FROM orders
RETURNING *
RETURNING позволяет сразу вернуть удалённые строки как результирующий набор, не выполняя повторный SELECT.WITH moved AS (...)
CTE превращает результат удаления во временный набор данных, который можно использовать в следующей операции:INSERT INTO orders_archive
SELECT * FROM moved;
В итоге строки удаляются и архивируются одним атомарным запросом, без повторного чтения таблицы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🤝14🔥10❤1
This media is not supported in your browser
VIEW IN TELEGRAM
Это большой гайд по SQL, где последовательно объясняется, как работать с базами данных и писать запросы. На сайте разбираются фундаментальные вещи: что такое SQL, как устроены таблицы и базы данных, как выполнять запросы, проверять данные и взаимодействовать с сервером через язык запросов. Отличный ресурс, если хочешь разобраться в SQL с практической стороны и понять работу баз данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤8🔥7🤝2
SEMI JOIN через EXISTS — как корректно проверять наличие связанных строк!
Частая задача в SQL — выбрать строки из одной таблицы, если в другой таблице существует хотя бы одна связанная запись.
Таблицы:
Нужно получить клиентов, у которых есть хотя бы один заказ.
Попытка через
Запрос вернёт клиентов, но если у клиента несколько заказов, он появится в результате несколько раз.
Чтобы убрать дубликаты, часто добавляют
Результат будет корректным, однако такой запрос выражает задачу менее точно:
В подобных задачах фактически требуется semi join — вернуть строку из
В большинстве СУБД это обычно выражают через
Подзапрос проверяет наличие хотя бы одной строки в
Оптимизатор часто может завершить проверку сразу после нахождения первого совпадения, поэтому
Практический пример — клиенты, которые делали заказы после определённой даты:
Поэтому внутри обычно пишут:
или:
В контексте
🔥
➡️ SQL Ready | #практика
Частая задача в SQL — выбрать строки из одной таблицы, если в другой таблице существует хотя бы одна связанная запись.
Таблицы:
customers(id, name)
orders(id, customer_id, created_at)
Нужно получить клиентов, у которых есть хотя бы один заказ.
Попытка через
JOIN:SELECT
c.id,
c.name
FROM customers c
JOIN orders o
ON o.customer_id = c.id;
Запрос вернёт клиентов, но если у клиента несколько заказов, он появится в результате несколько раз.
Чтобы убрать дубликаты, часто добавляют
DISTINCT:SELECT DISTINCT
c.id,
c.name
FROM customers c
JOIN orders o
ON o.customer_id = c.id;
Результат будет корректным, однако такой запрос выражает задачу менее точно:
JOIN формирует строки для каждого совпадения, а DISTINCT затем устраняет повторяющиеся значения.В подобных задачах фактически требуется semi join — вернуть строку из
customers, если существует хотя бы одна связанная строка в orders.В большинстве СУБД это обычно выражают через
EXISTS:SELECT
c.id,
c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
);
Подзапрос проверяет наличие хотя бы одной строки в
orders, связанной с текущим клиентом.Оптимизатор часто может завершить проверку сразу после нахождения первого совпадения, поэтому
EXISTS является естественным инструментом для проверки существования строк.Практический пример — клиенты, которые делали заказы после определённой даты:
SELECT
c.id,
c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
AND o.created_at >= '2025-01-01'
);
EXISTS не возвращает данные из подзапроса — он только проверяет факт существования строки.Поэтому внутри обычно пишут:
SELECT 1
или:
SELECT *
В контексте
EXISTS список выбираемых выражений не влияет на результат.EXISTS — стандартный и выразительный способ реализовать semi join. Он точно отражает намерение запроса и часто позволяет оптимизатору построить более эффективный план выполнения.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥9❤6🤝6
В этой статье:
• Разбирается, почему классический RAG плохо подходит для долгоживущих AI-агентов;
• Показана архитектура когнитивной памяти на SQLite: граф узлов и рёбер, сущности, гибридный поиск и механизм разрешения конфликтов знаний;
• Объясняется, как реализовать память агента с механизмом забывания и консолидацией фактов.🔊 Продолжайте читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍7🔥6🤝3
Передавайте списки значений через массивы вместо длинных IN!
Когда из приложения нужно передать список
PostgreSQL умеет принимать массив и сравнивать его через
Приложение просто передаёт массив параметром, а текст запроса остаётся неизменным независимо от длины списка:
На практике полезно явно указывать тип массива
🔥 Этот паттерн особенно удобен для
➡️ SQL Ready | #совет
Когда из приложения нужно передать список
id в SQL, многие пишут IN (... , ... , ...), что увеличивает текст SQL и усложняет работу с prepared statements:WHERE id IN (1,2,3,4,5,6,7)
PostgreSQL умеет принимать массив и сравнивать его через
ANY — это короче и позволяет избежать генерации динамического SQL:WHERE id = ANY($1)
Приложение просто передаёт массив параметром, а текст запроса остаётся неизменным независимо от длины списка:
SELECT *
FROM users
WHERE email = ANY($1);
На практике полезно явно указывать тип массива
($1::bigint[]), а также помнить, что NULL внутри массива влияет на результат сравнения.batch-запросов, API-фильтров и массовых выборок, где количество значений может сильно меняться.Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥12❤10
👍12🔥7🤝7❤2👎2
VACUUM — чистим таблицу и ускоряем работу базы!
В большинстве СУБД удалённые или обновлённые строки не удаляются мгновенно, а остаются как «мертвые» записи. Со временем это замедляет запросы и увеличивает размер таблиц — нужна очистка.
Сначала удаляем устаревшие записи из таблицы:
Однако физически строки всё ещё занимают место.
Чтобы освободить пространство и обновить статистику, запускаем:
Для диагностики можно получить подробный отчёт о процессе очистки:
🔥 Регулярный
➡️ SQL Ready | #практика
В большинстве СУБД удалённые или обновлённые строки не удаляются мгновенно, а остаются как «мертвые» записи. Со временем это замедляет запросы и увеличивает размер таблиц — нужна очистка.
Сначала удаляем устаревшие записи из таблицы:
DELETE FROM sessions WHERE expired = true;
Однако физически строки всё ещё занимают место.
Чтобы освободить пространство и обновить статистику, запускаем:
VACUUM ANALYZE sessions;
Для диагностики можно получить подробный отчёт о процессе очистки:
VACUUM VERBOSE sessions;
🔥 Регулярный
VACUUM поддерживает производительность и точность планов запросов.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤9👍9
PostgreSQL работает через процессы и shared memory, а системой управляет Postmaster и фоновые процессы. MySQL использует слоистую архитектуру: подключение, обработка SQL и storage engine (например InnoDB).
На картинке — основные компоненты и различия архитектуры двух популярных СУБД.
Сохрани, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16❤10👍8🤝2
Получение top-N строк с учётом равных значений!
Иногда нужно получить не просто N строк, а все записи, которые имеют такое же значение сортировки, как и последняя строка в выборке.
Это полезно для топ-продаж, логов и аналитики.
Обычный
Это удобно для построения top-N выборок, где несколько строк могут делить одно и то же место:
🔥 Такой приём позволяет строить top-выборки без дополнительных подзапросов и оконных функций.
➡️ SQL Ready | #совет
Иногда нужно получить не просто N строк, а все записи, которые имеют такое же значение сортировки, как и последняя строка в выборке.
Это полезно для топ-продаж, логов и аналитики.
FETCH FIRST 5 ROWS ONLY
Обычный
LIMIT / FETCH возвращает ровно N строк и может «обрезать» записи с таким же значением сортировки.WITH TIES возвращает все строки, у которых значение ORDER BY совпадает с последней строкой результата:FETCH FIRST 5 ROWS WITH TIES
Это удобно для построения top-N выборок, где несколько строк могут делить одно и то же место:
ORDER BY score DESC
FETCH FIRST 10 ROWS WITH TIES
WITH TIES не заменяет RANK() / DENSE_RANK(), если нужен полноценный рейтинг с номером места. Также проверьте синтаксис в вашей СУБД (например, в SQL Server используется TOP ... WITH TIES).Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍8❤7🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
Здесь разобраны реальные примеры запросов: выборки, фильтрация, JOIN-ы, подзапросы, агрегации и другие ключевые конструкции, которые чаще всего используются при работе с базами данных. Формат максимально простой: пример, объяснение, результат, поэтому можно быстро понять, как работает конкретный запрос и сразу применить его в своих задачах.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥8🤝8
PostgreSQL: CONCAT_WS, если нужно нормально собрать строку из колонок с NULL!
Частая мелочь в SQL — собрать одну строку из нескольких полей. Например, имя пользователя из
Таблица условно такая:
Первое, что обычно пишут:
И тут важный момент: если хотя бы одно значение NULL, всё выражение тоже уйдёт в NULL.
То есть если
В таких случаях удобнее использовать
Если
Плюс не нужно отдельно думать про лишние пробелы — разделитель вставится только там, где есть значение.
Важно:
То же самое можно собрать и через
Но это уже выглядит тяжелее, особенно когда полей больше двух-трёх.
🔥 Так что для таких кейсов
➡️ SQL Ready | #практика
Частая мелочь в SQL — собрать одну строку из нескольких полей. Например, имя пользователя из
first_name, middle_initial, last_name.Таблица условно такая:
users(id, first_name, middle_initial, last_name)
Первое, что обычно пишут:
SELECT first_name || ' ' || middle_initial || ' ' || last_name
FROM users;
И тут важный момент: если хотя бы одно значение NULL, всё выражение тоже уйдёт в NULL.
То есть если
middle_initial = NULL, то результат будет не Emily Johnson, а просто NULL.В таких случаях удобнее использовать
CONCAT_WS:SELECT CONCAT_WS(' ', first_name, middle_initial, last_name)
FROM users;CONCAT_WS склеивает значения через разделитель и просто пропускает NULL.Если
middle_initial = 'A': Emily A Johnson. Если middle_initial = NULL: Emily Johnson.Плюс не нужно отдельно думать про лишние пробелы — разделитель вставится только там, где есть значение.
Важно:
CONCAT_WS пропускает именно NULL. Пустая строка не игнорируется.То же самое можно собрать и через
COALESCE, например так:SELECT
COALESCE(first_name || ' ', '') ||
COALESCE(middle_initial || ' ', '') ||
COALESCE(last_name, '')
FROM users;
Но это уже выглядит тяжелее, особенно когда полей больше двух-трёх.
CONCAT_WS обычно самый нормальный вариант: и короче, и читается лучше.Please open Telegram to view this post
VIEW IN TELEGRAM
❤16🔥10👍9
В этой статье:
• Объясняется, как на самом деле работают оконные функции в SQL и почему результаты иногда отличаются от ожидаемых;
• Разбираются ключевые типы оконных фреймов — ROWS, RANGE и GROUPS, а также их влияние на вычисления;
• Показано, как правильно задавать границы окна (UNBOUNDED PRECEDING, CURRENT ROW, FOLLOWING) для накопительных итогов, скользящих средних и аналитических запросов.🔊 Продолжайте читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤8🔥8
Основные функции обработки строк в Oracle SQL: извлечение подстрок, определение позиции подстроки, вычисление длины строки, преобразование регистра, удаление лишних символов по краям, замена фрагментов текста и дополнение строки до заданной длины.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14🤝8❤7👍1