И смешно и грустно. Но по моему опыту ИИ неплохие результаты показывает, ибо многие аналитики предочитают не думать об оптимизации запросов, ибо целью является, просто получение нужных данных через страдания CPU и прочих механизмов сервера 🖥
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣10👾4🔥2🤔1
Привет, сегодня факультативный пост без разборов кода. Все слышали про SQL, многие с ним работали и работают, но давайте разберем откуда он вобще взялся и почему стал так популярен. Это язык, который пережил несколько поворотных технологических эпох в мире ИТ и до сих пор является самым актуальным и популярным инструментом управления данными.
🛠 Рождение: 1970-е
В реальности — получилось не совсем так.
🛠 Стандартизация и рост
🧊 Реальный мир
🧊 SQL сегодня
Сегодня есть ряд глобальных проблем, среди них:
Некоторые плюсы:
Вобщем, SQL, еще долго будет с нами, полноценного альтернативного решения, еще не изобрели, так что учим)
#История_SQL #SQL
Please open Telegram to view this post
VIEW IN TELEGRAM
💯9👾6 4🔥2
При проектировании таблиц в реляционных базах данных важно выбрать тип данных для первичного ключа. От него зависят скорость запросов, обеспечение уникальности, масштабируемость и даже архитектура системы. Даже если вы не проектируете БД, понимание ключей поможет в работе с данными.
В этом посте рассмотрим три популярных способа генерации первичных ключей: INT, BIGINT и UUID.
🛠 INT — автоинкрементный числовой ключ.
Используется по умолчанию в большинстве проектов. Он требует минимум места, обеспечивает быструю сортировку и фильтрацию по индексу, хорошо читается в логах, легко реализуется средствами СУБД. Но у INT есть потолок (2.1 млрд значений) и ограниченная масштабируемость: при распределении на несколько серверов ID могут пересекаться. А ещё ID легко угадываются, что делает структуру базы предсказуемой.
🛠 BIGINT — INT с запасом на вырост.
То же самое, только 64 бита. Решает проблему переполнения — хватит на миллиарды строк. Сохраняет читаемость, скорость и простоту реализации. Поддерживается всеми современными СУБД. Но индекс и таблицы с такими ключами весят больше. А генерация ID всё ещё централизованная, что не даёт гибкости.
🛠 UUID (Universally Unique Identifier).
UUID создаётся независимо, без единого центра, что делает его идеальным для микросервисов, Kafka, offline-режимов и распределённых архитектур. Его сложно предсказать — это повышает безопасность. UUID легко интегрируется в API и события. Но UUID весит больше (16 байт), хуже индексируется, не читается глазами, не сортируется. Это может замедлять JOIN и вставки. Если важна хоть какая-то упорядоченность, используйте UUID v1 или v7 — они содержат метку времени.
🧊 Объемы генерации ключей в экземпляре таблицы.
Вы можете создать не более примерно 2 миллиардов уникальных записей с автоинкрементом INT. Если же использовать BIGINT, то его диапазон гораздо шире — он позволяет задать свыше 9 квинтиллионов уникальных значений, что на практике практически никогда не достигается.
С UUID ситуация другая: это 128-битное значение, которое генерируется случайным или псевдослучайным образом. Количество возможных значений настолько велико (2^128), что даже при создании миллиардов UUID-ключей в секунду вероятность столкнуться с дублем за всю историю человечества минимальна. Однако при этом UUID занимает больше места, как на диске, так и в оперативной памяти, и может замедлять индексацию.
Что выбрать?
#UUID #INT #BIGINT
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15💯4👾3 2🤣1
CTE (Common Table Expression) — это временный результирующий набор данных, определённый в WITH-блоке и используемый внутри основного SQL-запроса. Он существует только в рамках одного запроса и не сохраняется в базе.
По сути, это "виртуальная подтаблица", которую можно использовать как обычную таблицу, но без создания объекта в БД.
Зачем нужен CTE?
WITH имя_cte (опциональные_поля) AS (
SQL-запрос
)
SELECT ...
FROM имя_cte
...
WITH объявляет формирование CTE. Можно создавать несколько CTE за один раз, разделяя их запятыми:
WITH cte1 AS (...),
cte2 AS (...)
SELECT ...
FROM cte1
JOIN cte2 ...
Найти всех пользователей, которые заходили в систему за последние 30 дней, и посчитать, сколько заказов сделал каждый из них.
Атрибуты:
id name last_login
101 Иван 2025-07-20
105 Ольга 2025-07-15
109 Петр 2025-06-10
Атрибуты:
id user_id created_at
201 101 2025-07-21
203 101 2025-07-20
206 101 2025-07-22
202 105 2025-07-19
204 105 2025-07-22
205 105 2025-07-23
207 105 2025-07-24
208 105 2025-07-25
209 105 2025-07-26
210 105 2025-07-27
WITH active_users AS (
SELECT id AS user_id
FROM users
WHERE last_login > CURRENT_DATE - INTERVAL '30 days'
)
SELECT
u.user_id,
COUNT(o.id) AS orders_count
FROM active_users u
JOIN orders o ON o.user_id = u.user_id
GROUP BY u.user_id;
WITH active_users AS (...)
Создаём временный набор данных с именем active_users, в который попадут только те пользователи, чей last_login был в последние 30 дней.
CURRENT_DATE - INTERVAL '30 days'
Это дата 30 дней назад от текущей.
user_id
101
105
109
SELECT
u.user_id,
COUNT(o.id) AS orders_count
FROM active_users u
JOIN orders o ON o.user_id = u.user_id
GROUP BY u.user_id;
user_id orders_count
101 3
105 7
Пользователь 109, у которого нет заказов, не попадёт в результат — INNER JOIN исключает строки без соответствующих заказов. Чтобы включить таких пользователей и показать orders_count = 0, используйте LEFT JOIN
Когда точно стоит использовать CTE:
#CTE #SQL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20 6🤯5💯1👾1
🧊 Айсберг SQL
Однажды, наткнулся на забавный мем, который с каждым уровнем становится все сложнее и страшнее, посмеялся и забыл. А недавно нашёл статью на Хабр и оказалось, что у мема есть реальное практическое применение, ведь он, по сути, этап за этапом разбирает взаимодействие через SQL с СУБД PostgreSQL, а автор мема SQL-разработчик Джордан Льюис.
Так что можно использовать мем, чтобы выстроить свой путь изучения SQL, как методичку))
На этой неделе, кстати, опубликую пост, как быстро погрузиться в SQL, если вы новичок, и за пару недель (или меньше) достичь гордого уровня junior, минимально необходимого для прохождения собеседований.
Однажды, наткнулся на забавный мем, который с каждым уровнем становится все сложнее и страшнее, посмеялся и забыл. А недавно нашёл статью на Хабр и оказалось, что у мема есть реальное практическое применение, ведь он, по сути, этап за этапом разбирает взаимодействие через SQL с СУБД PostgreSQL, а автор мема SQL-разработчик Джордан Льюис.
Так что можно использовать мем, чтобы выстроить свой путь изучения SQL, как методичку))
На этой неделе, кстати, опубликую пост, как быстро погрузиться в SQL, если вы новичок, и за пару недель (или меньше) достичь гордого уровня junior, минимально необходимого для прохождения собеседований.
🔥28👾4🌚3 1
Набросал своеобразную карту навыков и знаний необходимых для базового, но уверенного понимания работы с реляционными БД. У поста будет еще вторая часть, больше про сами собесы и задачки на них. А пока основы:
Начинать нужно с основ. Вы должны понимать, как извлекать данные из таблиц и как управлять результатом запроса. Разберитесь с базовыми конструкциями:
Уже на этом этапе вы сможете решать до 40% практических задач, особенно из области аналитики или SQL-тестов на позицию junior.
В большинстве реальных задач данные разбросаны по нескольким таблицам. Чтобы собрать полную картину, нужно уметь соединять таблицы между собой. Разберитесь с основными типами соединений:
Понимание JOIN — обязательный навык. Ошибки в соединениях часто приводят к неверным результатам и срезают кандидатов на собеседованиях.
Вам нужно научиться считать и группировать данные, это важно для аналитики через SQL. Изучите:
На этой базе строится вся аналитика: подсчёты по клиентам, категориям, регионам и т.д.
Многие задачи связаны с анализом по дням, неделям, месяцам. Изучите:
Это часто встречается в SQL-задачах.
Часто задачи требуют промежуточных расчётов или сложной логики. Тут пригодятся:
Вложенные конструкции активно используются в продвинутой аналитике, автоматизированных отчётах и сложных тестовых заданиях.
Что из ресурсов могу посоветовать:
Это то, что помогает не просто писать код, а реально понимать, как устроен SQL и базы данных.
Для уверенного уровня Junior важно:
Продолжение следует
#Junior #SQL
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24👾11 8💯2🌚1
Работа с датами и временем — это неотъемлемая часть большинства SQL-запросов. Независимо от того, анализируете ли вы продажи по месяцам, фильтруете данные за определённый период или рассчитываете сроки выполнения задач — понимание работы с датами просто необходимо. Перед тем как начинать работать с датами, важно понять, как именно они хранятся в различных СУБД (определите вашу и погуглите какой синтаксис она приветствует), это поможет избежать множества ошибок и неожиданностей.
Дальше распишу функционал внутри кода, для наглядности.
Эти функции используются постоянно — для фильтрации свежих данных, создания временных меток, сравнения с прошлыми значениями.
-- Получаем только текущую дату (без времени)
-- Результат будет примерно таким: 2024-03-15
SELECT CURRENT_DATE;
-- Альтернатива:
SELECT CURDATE(); -- То же самое в MySQL
-- Получаем текущую дату и время
-- Результат будет примерно таким: 2024-03-15 16:45:30
SELECT NOW();
-- Альтернативы:
SELECT CURRENT_TIMESTAMP; -- То же самое, что и NOW()
SELECT LOCALTIME(); -- В некоторых СУБД
SELECT LOCALTIMESTAMP(); -- В некоторых СУБД
-- Получаем только текущее время (без даты)
-- Результат будет примерно таким: 16:45:30
SELECT CURRENT_TIME;
-- Альтернатива:
SELECT CURTIME(); -- То же самое в MySQL
Часто нужно получить отдельные части даты — год, месяц, день и т.д. Для этого используются функции извлечения.
-- Представим, что у нас есть таблица orders с полем created_at
-- Значение created_at: '2024-03-15 14:30:25'
SELECT
created_at, -- Исходное значение: 2024-03-15 14:30:25
-- Извлекаем год из даты
-- Результат: 2024
EXTRACT(YEAR FROM created_at) AS order_year,
-- Извлекаем месяц из даты
-- Результат: 3 (март)
EXTRACT(MONTH FROM created_at) AS order_month,
-- Извлекаем день месяца
-- Результат: 15
EXTRACT(DAY FROM created_at) AS order_day,
-- Извлекаем день недели (0 = воскресенье, 1 = понедельник, ...)
-- Результат: 6 (суббота)
EXTRACT(DOW FROM created_at) AS day_of_week,
-- Извлекаем день года (1-365/366)
-- Результат: 75 (15 марта — 75-й день года)
EXTRACT(DOY FROM created_at) AS day_of_year,
-- Извлекаем час
-- Результат: 14
EXTRACT(HOUR FROM created_at) AS order_hour,
-- Извлекаем минуты
-- Результат: 30
EXTRACT(MINUTE FROM created_at) AS order_minute,
-- Извлекаем секунды
-- Результат: 25
EXTRACT(SECOND FROM created_at) AS order_second,
-- Извлекаем квартал года (1-4)
-- Результат: 1 (первый квартал)
EXTRACT(QUARTER FROM created_at) AS quarter,
-- Извлекаем номер недели года (1-53)
-- Результат: 11
EXTRACT(WEEK FROM created_at) AS week_number
FROM orders
WHERE id = 123; -- Для примера берём конкретную запись
Завтра выложу вторую часть поста, где покажу работу с интервалами, вычисление дельт между датами и варианты форматирования дат.
#SQL #Даты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23 8👾4💯1
Привет, продолжаем разбор основ начатый в предыдущем посте. Там мы разобрали:
Для инфо синтаксис в коде постов пишу для PostgreSQL (как популярной промышленной СУБД, для других логика похожа, но синтаксис может отличаться, гуглите)
SQL позволяет выполнять математические операции с датами — добавлять/вычитать дни, месяцы, годы и другие временные интервалы.
-- Предположим, у нас есть дата: '2024-03-15 14:30:25'
SELECT
created_at, -- Исходная дата: 2024-03-15 14:30:25
-- Добавляем 7 дней (также можно и с месяцами - '2 months')
-- Результат: 2024-03-22 14:30:25
created_at + INTERVAL '7 days' AS one_week_later,
-- Вычитаем 3 дня
-- Результат: 2024-03-12 14:30:25
created_at - INTERVAL '3 days' AS three_days_ago,
-- Добавляем 1 год
-- Результат: 2025-03-15 14:30:25
created_at + INTERVAL '1 year' AS next_year,
-- Добавляем 3 часа
-- Результат: 2024-03-15 17:30:25
created_at + INTERVAL '3 hours' AS three_hours_later,
-- Добавляем 30 минут
-- Результат: 2024-03-15 15:00:25
created_at + INTERVAL '30 minutes' AS thirty_minutes_later,
-- Комбинируем интервалы
-- Результат: 2025-04-22 17:45:25 (через 1 год, 1 месяц, 7 дней, 3 часа, 15 минут)
created_at + INTERVAL '1 year' + INTERVAL '1 month' + INTERVAL '7 days' +
INTERVAL '3 hours' + INTERVAL '15 minutes' AS complex_interval
FROM orders
WHERE id = 123;
Часто нужно узнать, сколько времени прошло между двумя событиями — для этого есть специальные функции.
-- Считаем разницу между двумя конкретными датами в днях
-- Результат: 7 (разница в днях между 15 марта и 22 марта)
SELECT '2024-03-22'::date - '2024-03-15'::date AS days_difference;
-- Считаем разницу между датой заказа и текущей датой
SELECT
created_at, -- Дата создания заказа
-- Текущая дата
CURRENT_DATE,
-- Сколько дней прошло с момента создания заказа
-- Если результат отрицательный - заказ из будущего
-- Если положительный - сколько дней прошло
CURRENT_DATE - created_at::date AS days_since_order,
-- Альтернативный способ: сколько дней до будущей даты
'2024-12-31'::date - CURRENT_DATE AS days_until_new_year
FROM orders
WHERE id = 123;
Иногда нужно представить дату в определённом формате — для отчётов, пользовательского интерфейса и т.д.
-- Исходная дата: '2024-03-15 14:30:25'
-- Хотим получить различные форматы отображения
SELECT
created_at, -- Исходное значение: 2024-03-15 14:30:25
-- Форматируем как: 15.03.2024
-- DD = день (01-31), MM = месяц (01-12), YYYY = год (4 цифры)
TO_CHAR(created_at, 'DD.MM.YYYY') AS formatted_date_1,
-- Форматируем как: 15/03/24 (день/месяц/год 2 цифры)
-- YY = год (2 цифры)
TO_CHAR(created_at, 'DD/MM/YY') AS formatted_date_2,
-- Форматируем как: 15 марта 2024
-- Month = полное название месяца
TO_CHAR(created_at, 'DD Month YYYY') AS formatted_date_3,
-- Форматируем как: Пятница, 15 марта 2024
-- Day = полное название дня недели, Month = полное название месяца
TO_CHAR(created_at, 'Day, DD Month YYYY') AS formatted_date_4,
-- Форматируем как: 2024-03-15 (ISO формат)
TO_CHAR(created_at, 'YYYY-MM-DD') AS iso_date,
-- Форматируем время как: 14:30
-- HH24 = час (00-23), MI = минуты (00-59)
TO_CHAR(created_at, 'HH24:MI') AS time_only,
-- Форматируем как: 15.03.2024 14:30
TO_CHAR(created_at, 'DD.MM.YYYY HH24:MI') AS datetime_formatted
FROM orders
WHERE id = 123;
В следующем посте и заключительном по основам, разберем пару реальных задач и я дам несколько полезных советов по работе в этой области.
#SQL #Даты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14🤣7👾6 4🤯1
Привет, сегодня лайтовая история про создателя 2-х весьма популярных СУБД, решил писать больше такого контента, а не только делать разборы запросов)
Итак, слышал про MySQL?
Это не просто СУБД — это фундамент, на котором вырос весь интернет 2000-х. А придумал её финский программист — почти в одиночку. Его зовут Микаэль "Монти" Видениус.
Разработчики в восторге: «Наконец-то альтернатива Oracle, за которую не нужно платить тысячи долларов!»
MySQL становится стандартом веба.
Казалось бы — успех! Но:
Oracle вынужден развивать MySQL: слишком много зависимых проектов. А MariaDB растёт и отбирает долю рынка.
Живёт в Финляндии, пишет код, ему за 60. Не миллиардер. Просто инженер, который сделал интернет и работу с БД удобнее.
А ты бы выбрал миллиарды — или свободу кода?
#SQL #Факты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24😱7👾4 3💯1
Всем привет)) Совместно @simulative_official организуем буткемп по SQL, регистрация доступна уже сейчас, буду рад вашему участию 👩💻
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👾4 3💯1
Forwarded from Simulative
Привет, аналитики! Меня зовут Владимир Лунев. Более 5 лет я работаю в IT как бизнес- и системный аналитик.
Я строил процессы и архитектуру реляционных баз данных для аналитиков, чтобы они могли быстро получить качественные данные, а не заниматься ручной обработкой исходной информации. Большую часть карьеры провёл в ритейле, где ежедневно принимаются решения на основе больших потоков данных: продаж, запасов, логистики, прогнозов спроса.
Несколько кейсов из моей работы:
👑 Оптимизировал отчёт и сократил время его выполнения с 3 часов, до 30 минут, не переписывая бизнес-логику, а разобрав EXPLAIN и исправив ошибки SQL-запросов.
👑 Построил систему контроля качества данных на основании проверочных скриптов, которая автоматически ловила дубли, NULL-ловушки и логические противоречия до попадания информации в отчёты.
👑 Разработал автоматизированный процесс агрегации и расчёта KPI для сети магазинов, позволивший ежедневно получать корректные метрики без ошибок.
Я буду ведущим SQL-буткемпа — практикума, где вы получите реальные навыки, которые работают в боевых проектах бизнеса. В рамках буткемпа мы разберём:
➖ Оптимизацию запросов в SQL — разбор EXPLAIN, выявление «тормозящих» мест, исправление лишних подзапросов и «фантомных» строк для ускорения критичных бизнес-отчётов и выгрузок.
➖ Контроль качества данных — научимся писать кастомные скрипты проверок данных для точных и надёжных данных.
➖ Прогнозы и тренды — построение когорт, скользящих метрик, lag/lead-анализ и простые линейные прогнозы для точного планирования.
➖ Сценарный анализ «что если» — моделирование альтернатив через параметризацию, temp-таблицы и CTE, автоматизация расчётов для оценки влияния изменений на ключевые показатели.
➖ Агрегацию данных и полезные бизнес-метрики — расчёт growth, hitrate, долей, YoY, контроль перекосов и проведение A/B-анализов для оценки эффективности решений.
➖ Рекурсию и последовательности — поработаем с деревьями parent-child, обходом графов, кластеризацией и сегментацией пользовательских действий для глубокого анализа процессов.
Формат: много практики на кейсах и задачах из IT-проектов и немного сопутствующей теории.
Если вы хотите писать SQL-запросы так, чтобы данные реально работали на вас, а не наоборот — этот буткемп для вас!
➡️ Зарегистрироваться на буткемп по ранней цене
📊 Simulative
Я строил процессы и архитектуру реляционных баз данных для аналитиков, чтобы они могли быстро получить качественные данные, а не заниматься ручной обработкой исходной информации. Большую часть карьеры провёл в ритейле, где ежедневно принимаются решения на основе больших потоков данных: продаж, запасов, логистики, прогнозов спроса.
Я часто сталкивался с задачами, где точность и скорость обработки данных имели критическое значение: приходилось быстро выявлять скрытые ошибки, обеспечивать корректность бизнес-отчётов и автоматизировать расчёты ключевых показателей.
Несколько кейсов из моей работы:
Я буду ведущим SQL-буткемпа — практикума, где вы получите реальные навыки, которые работают в боевых проектах бизнеса. В рамках буткемпа мы разберём:
Формат: много практики на кейсах и задачах из IT-проектов и немного сопутствующей теории.
Буткемп будет полезен аналитикам, data-engineers, backend-разработчикам, а также всем, кто работает с массивами данных, строит отчёты и хочет улучшить навыки владения SQL.
Если вы хотите писать SQL-запросы так, чтобы данные реально работали на вас, а не наоборот — этот буткемп для вас!
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥10😱5👾3💯2🗿2
Когда вы работаете с большими таблицами, часто не нужны все строки сразу. Например, вы хотите:
Для этого в SQL есть два оператора (точнее clauses): LIMIT и OFFSET.
LIMIT ограничивает количество строк, которое вернёт запрос.
Пример:
SELECT *
FROM products
ORDER BY price DESC
LIMIT 5; -- берём только 5 самых дорогих товаров
Что происходит:
OFFSET пропускает указанное количество строк перед выборкой.
Пример:
SELECT *
FROM products
ORDER BY price DESC
LIMIT 5 OFFSET 5; -- берём строки с 6 по 10
Что происходит:
LIMIT + OFFSET идеально подходят для страниц сайта или приложения (бэк UI), но можно юзать и при подготовке отчетности, если ложиться в условия ее формирования.
-- Страница 1
SELECT * FROM orders ORDER BY order_date DESC LIMIT 20 OFFSET 0;
-- Страница 2
SELECT * FROM orders ORDER BY order_date DESC LIMIT 20 OFFSET 20;
-- Страница 3
SELECT * FROM orders ORDER BY order_date DESC LIMIT 20 OFFSET 40;
Каждый раз вы берёте новую порцию данных без лишней нагрузки на базу.
Случайные строки с LIMIT.
Чтобы взять случайные строки из таблицы:
SELECT *
FROM users
ORDER BY RANDOM() -- в разных СУБД отличается
LIMIT 5;
LIMIT в подзапросах.
Можно использовать LIMIT для выборки топ-N в подзапросах:
SELECT *
FROM users
WHERE id IN (
SELECT id
FROM users
ORDER BY created_at DESC
LIMIT 10
);
Всегда используйте ORDER BY с LIMIT. Иначе “первые N” строки могут быть случайными.
LIMIT n — Берёт первые n строк
OFFSET m — Пропускает первые m строк
LIMIT n OFFSET m — Берёт n строк, пропустив первые m
Запомните: LIMIT — сколько строк грузить, OFFSET — с какой строки грузить.
#SQL #LIMIT #OFFSET
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥15 7👾5
Forwarded from Simulative
Узнайте, почему ваши SQL-запросы тормозят 🤖
Медленные SQL-запросы могут стоить бизнесу миллионов: отчёты считаются часами, решения принимаются с задержкой, а ошибки в данных подрывают доверие к аналитике.
На вебинаре Владимир Лунев, бизнес- и системный аналитик с 5-летним опытом работы в ритейле и IT, разберёт 7 реальных кейсов оптимизации SQL-запросов, которые помогали бизнесу принимать быстрые и точные решения.
В ходе вебинара разберём:
🟠 Как понять, что запрос тормозит, и чем это грозит бизнесу;
🟠 Как читать план выполнения (EXPLAIN, EXPLAIN ANALYZE) и находить ошибки;
🟠 Типовые причины медленных запросов и как их исправлять;
🟠 7 реальных кейсов из практики: «было → стало» с разбором кода.
❗️ Встречаемся 24 сентября в 19:00 МСК.
➡️ Зарегистрироваться на вебинар
📊 Simulative
Медленные SQL-запросы могут стоить бизнесу миллионов: отчёты считаются часами, решения принимаются с задержкой, а ошибки в данных подрывают доверие к аналитике.
На вебинаре Владимир Лунев, бизнес- и системный аналитик с 5-летним опытом работы в ритейле и IT, разберёт 7 реальных кейсов оптимизации SQL-запросов, которые помогали бизнесу принимать быстрые и точные решения.
В ходе вебинара разберём:
🧡 Обязательно ждём вас в лайве — вы сможете напрямую задать свои вопросы Владимиру Луневу и получить ценный опыт оптимизации SQL-запросов!
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥9 5💯4🤔2🤣1
Какой СУБД вы пользуетесь сейчас?
Anonymous Poll
61%
PostgreSQL
9%
MySQL / MariaDB
6%
Oracle
1%
SQLite
6%
ClickHouse
0%
MongoDB
0%
NoSQL СУБД
5%
Другая (укажите в комментариях)
11%
Только начинаю изучать СУБД
🔥5 5🌚1💯1
Многие думают, что оператор HAVING — это просто аналог WHERE, но после GROUP BY. Это упрощение, которое может привести к путанице. Давайте разберём настоящую теорию — шаг за шагом.
Здесь нужно понимать, что SQL-запрос выполняется СУБД не в том порядке, в котором он написан человеком. Это критически важно для понимания HAVING.
1. FROM — загрузка данных из таблиц(ы)
2. WHERE — фильтрация отдельных строк
3. GROUP BY — разбиение оставшихся строк на группы
4. Вычисление агрегатных функций (COUNT, SUM, AVG и т.д.) для каждой группы
5. HAVING — фильтрация групп на основе результатов агрегации
6. SELECT — формирование выходных колонок (включая алиасы)
7. ORDER BY, LIMIT, и т.д.
SQL основан на реляционной алгебре. Оператор GROUP BY трансформирует отношение (таблицу) в множество групп, где каждая группа — это подмножество строк с одинаковым значением ключа группировки.
Пример:
GROUP BY department
Cоздаёт столько групп, сколько уникальных значений в колонке department. Каждая такая группа — новая логическая единица, и к ней можно применять агрегатные функции, которые сводят множество строк к одному значению (например, средняя зарплата в отделе).
Потому что WHERE работает на уровне кортежей (строк), а не групп. Он отвечает на вопрос: «Оставить ли эту конкретную строку в результирующем наборе до группировки?». Агрегатные функции, напротив, не определены для одной строки — они требуют множества. Например, AVG(salary) для одной строки — это просто salary, но SQL не позволяет так делать в WHERE, чтобы избежать семантической неоднозначности.
Используй HAVING, когда твоё условие зависит от результата агрегации по группе.
Найдём отделы, где средняя зарплата больше 70 000.
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 70000;
Если попытаться написать это через WHERE — получим ошибку:
WHERE AVG(salary) > 70000
-- СУБД заруинила запрос
Потому что на этапе WHERE ещё нет групп, а значит — нет и средней зарплаты по отделу.
Используй WHERE, если фильтруешь по конкретным значениям (например, status = 'active').
Используй HAVING, если фильтруешь по результатам агрегации (COUNT(*) > 5, AVG(price) < 100).
#SQL #HAVING
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29💯9👾5 2🤔1
Если вы задумывались над тем, чем же все-таки занимаются аналитики, рекомендую подписаться на канал Data Brew!
Канал ведет тот самый аналитик, который смог построить карьеру после курсов и сейчас продолжает расти профессионально.
Автор
🤗 помогает в поиске работы
😊 пишет о полезных для аналитиков хардах
🎁 делится реальными историями с собеседований
🤬 рассказывает о боли аналитиков
😇 скидывает аналитические мемы
Подписывайся на @data_brew
Канал ведет тот самый аналитик, который смог построить карьеру после курсов и сейчас продолжает расти профессионально.
Автор
Подписывайся на @data_brew
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥7👾4 4
🐘 От академического проекта до лидера open-source: история PostgreSQL
Продолжим тему постов про историю SQL и СУБД, ранее мы уже разбирали:
➖ Как создатель MySQL потерял миллиарды
➖ Историю SQL: от лаборатории IBM до ядра современного ИТ
Теперь настало время одной из самых популярных промышленных СУБД — PostgreSQL
❗️ Начало, проект "Ingres"
Всё началось в 1986 году в Калифорнийском университете в Беркли. Группа исследователей под руководством профессора Майкла Стоунабрейкера уже создала реляционную СУБД Ingres — одну из первых в мире. Но им захотелось большего. Они решили пойти дальше реляционной модели и создать объектно-реляционную СУБД, которая поддерживала бы сложные типы данных, наследование и пользовательские функции. Так родился проект Post-Ingres — "после Ingres".
❗️ Рождение open-source
В 1994 году два аспиранта Андреас Энглесберг и Джонсон Ло портировали Postgres на язык C и добавили поддержку SQL. Это стало поворотным моментом. В том же году код был открыт под лицензией BSD и началась эра сообщества. В 1996 году название изменили на PostgreSQL, чтобы подчеркнуть совместимость со стандартом.
PostgreSQL — одна из самых старых open-source СУБД, которая активно развивается без корпоративного владельца. Никакой Oracle, Microsoft или Google за спиной — только сообщество энтузиастов и профессионалов.
❗️ Эволюция версий: от 6.0 до 16+
➖ 1996: Выходит PostgreSQL 6.0 — первая официальная версия с SQL.
➖ 1997: Появляется поддержка транзакций и многоверсионного контроля параллелизма (MVCC) — технологии, которая сегодня лежит в основе производительности PostgreSQL.
➖ 2005: Версия 8.0 — первая нативная сборка для Windows.
➖ 2010: Поддержка JSON (ещё до бума NoSQL!).
➖ 2012: JSONB — бинарный, индексируемый JSON. Это стало прорывом: PostgreSQL начал конкурировать с документными базами.
➖ 2018: Версия 11 — параллельное создание индексов, улучшенная масштабируемость.
➖ 2023: PostgreSQL 16 — улучшения в логической репликации, безопасность, производительность аналитических запросов.
➖ 2025: Ожидаеться выход версии 18
PostgreSQL поддерживает более 40 расширяемых типов данных, включая географические (PostGIS), полнотекстовый поиск, массивы, диапазоны, UUID, IP-адреса и даже пользовательские типы.
❗️ Почему PostgreSQL так популярен?
➖ Следует SQL-стандартам лучше, чем многие коммерческие СУБД.
➖ Можно добавлять свои типы, функции, операторы, даже языки программирования (PL/Python, PL/Perl и др.).
➖ ACID-совместимость, отказоустойчивость, репликация.
➖ Более 1000 активных контрибьюторов, регулярные релизы раз в год, никакого vendor lock-in.
Компании вроде Apple, Spotify, Reddit, Cisco и IMDb, Магнит, Яндекс, Сбер используют PostgreSQL в продакшене — иногда с тысячами серверов.
🐘 А почему слон?
➖ Идея слона как символа PostgreSQL появилась в 1997 году — её предложил участник сообщества Дэвид Янг, вдохновлённый детективом Агаты Кристи «Слоны умеют помнить».
➖ В апреле 1999 года в Санкт-Петербурге руководитель небольшой дизайн-студии Дмитрий Самерсов инициировал создание логотипа, а дизайнер Екатерина Папчинская нарисовала эскиз — знаменитого "слона в алмазе"
➖ 12 апреля 1999 года изображение под названием slonik.gif было выложено на сайт Дмитрия и отправлено в рассылку pgsql-hackers. Название мгновенно прижилось и стало легендой международного сообщества. Позже логотип стилизовался и пришел к современному варианту.
❗️ Будущее
PostgreSQL продолжает развиваться:
➖ Улучшение работы с AI/ML (через расширения вроде MADlib),
➖ Поддержка векторных встраиваний (для поиска по схожести — актуально для LLM!),
➖ Ещё более мощная логическая репликация,
➖ Оптимизация для облачных и распределённых сред.
❗️ В заключение
Постгре это не просто база данных — это живая легенда с более чем 35-летней историей, открытая для всех и созданная благодаря уму, упорству и страсти к качеству.
И всё это — благодаря университетскому проекту 1980-х, который отказался умирать.
#SQL
📱 Подписаться на канал
💻 Курс автора по SQL DDL
🌎 Мой ИТ-стартап
Продолжим тему постов про историю SQL и СУБД, ранее мы уже разбирали:
Теперь настало время одной из самых популярных промышленных СУБД — PostgreSQL
Всё началось в 1986 году в Калифорнийском университете в Беркли. Группа исследователей под руководством профессора Майкла Стоунабрейкера уже создала реляционную СУБД Ingres — одну из первых в мире. Но им захотелось большего. Они решили пойти дальше реляционной модели и создать объектно-реляционную СУБД, которая поддерживала бы сложные типы данных, наследование и пользовательские функции. Так родился проект Post-Ingres — "после Ingres".
В 1994 году два аспиранта Андреас Энглесберг и Джонсон Ло портировали Postgres на язык C и добавили поддержку SQL. Это стало поворотным моментом. В том же году код был открыт под лицензией BSD и началась эра сообщества. В 1996 году название изменили на PostgreSQL, чтобы подчеркнуть совместимость со стандартом.
PostgreSQL — одна из самых старых open-source СУБД, которая активно развивается без корпоративного владельца. Никакой Oracle, Microsoft или Google за спиной — только сообщество энтузиастов и профессионалов.
PostgreSQL поддерживает более 40 расширяемых типов данных, включая географические (PostGIS), полнотекстовый поиск, массивы, диапазоны, UUID, IP-адреса и даже пользовательские типы.
Компании вроде Apple, Spotify, Reddit, Cisco и IMDb, Магнит, Яндекс, Сбер используют PostgreSQL в продакшене — иногда с тысячами серверов.
🐘 А почему слон?
PostgreSQL продолжает развиваться:
Постгре это не просто база данных — это живая легенда с более чем 35-летней историей, открытая для всех и созданная благодаря уму, упорству и страсти к качеству.
И всё это — благодаря университетскому проекту 1980-х, который отказался умирать.
#SQL
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥16 10🤯3👾2
Когда я только начал работать аналитиком, я думал, что база данных это просто место, где хранятся цифры. Потом я потратил два дня на отчёт, который оказался неверным, потому что не знал: поле status в таблице orders может быть NULL, если заказ ещё не обработан системой.
Но документации по этому поводу не было и узнал я об этом потом только со слов коллег. С тех пор я понял - реляционная модель это не про данные. Это про доверие.
В IT мы привыкли к API: чёткие контракты, типы, документация.
Например, если в колонке user_id есть NULL, значит, система допускает анонимные действия. Это бизнес-решение, зафиксированное в схеме (надеюсь).
Если договор нарушен (например, внезапно появляются дубли без первичного ключа), все теряют доверие к данным.
Это как менять API без версионирования - клиенты падают, но никто не знает почему.
Реляционная модель, не техническая деталь. Это язык согласия между людьми, которые хотят говорить об одном и том же, не путаясь.
Хорошая схема это когда новый аналитик через неделю понимает бизнес, просто читая документацию по модели данных БД.
Посмотрите на любую таблицу в вашей БД. Спросите себя:
Если да - вы знаете, с чего начать укреплять договор.
И напоследок анекдот:
Новичок приходит в команду и спрашивает:
— Где почитать про модель данных БД?
— Вся документация в голове у Артёма — отвечает тимлид.
— А как с ним связаться?
— А… он уволился полгода назад.
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥16 5💯4
Когда вы видите NULL в таблице, интуиция подсказывает: "Это просто пусто. Ничего нет. Поле не заполнено".
Но реляционная модель намеренно отказывается от такого упрощения. Вместо "ничего" она вводит состояние неопределённости: значение существует, но нам о нём ничего не известно. Именно поэтому NULL - это не данные, а метаинформация о недостатке данных.
И эта тонкость ломает привычную булеву логику, заставляя SQL работать с трёхзначной логикой (3VL):
Рассмотрим запрос:
SELECT name FROM employees WHERE age = NULL;
Логика кажется простой: "выведи всех, у кого возраст не указан"
Но СУБД думает иначе. Выражение вида age = NULL не возвращает ни TRUE, ни FALSE.
Поскольку NULL обозначает отсутствие известного значения, сравнение любого выражения с NULL с использованием стандартных операторов (=, <>, <, >, и т.д.) всегда приводит к логическому значению UNKNOWN.
Согласно семантике WHERE, в результирующий набор включаются только те строки, для которых условие оценивается как TRUE. Значения FALSE и UNKNOWN в этом контексте ведут себя одинаково - соответствующие строки исключаются из вывода.
Следовательно, конструкция из примера никогда не возвращает строк, даже если в столбце age присутствуют значения NULL.
Правильный синтаксис - специальный оператор:
SELECT name FROM employees WHERE age IS NULL; -- также антипод IS NOT NULL
Здесь вы не сравниваете значения, а запрашиваете состояние. Эти предикаты предназначены именно для работы с состоянием неопределённости и возвращают строго TRUE или FALSE.
Большинство агрегатов (SUM, AVG, MAX, MIN) игнорируют NULL. Это не ошибка, это следствие семантики "неизвестно":
Пример:
Таблица salaries:
id | amount
1 | 5000
2 | NULL
3 | 7000
Запрос:
SELECT AVG(amount) FROM salaries; -- Результат: 6000 (а не 4000!)
Если вы сознательно хотите трактовать NULL как 0 (например, "не заплатили - значит, ноль"), используйте COALESCE или CASE:
SELECT AVG(COALESCE(amount, 0)) FROM salaries; -- Теперь: 4000
Но будьте осторожны, это меняет семантику данных. Вы переходите от "мы не знаем" к "мы знаем, что это ноль"
ORDER BY column NULLS LAST
#SQL #NULL
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥21 9👾4💯2🌚1