CASEТут ниже представлена попытка заNULLить значение, если оно равно чему-то.
, CASE WHEN sdate = '1900-01-01' THEN NULL ELSE sdate END sdate
, CASE WHEN mdate = '1900-01-01' THEN NULL ELSE mdate END mdate
Но ведь в PostgreSQL есть функция
nullif, которая делает ровно то же самое.NULLIF(значение1, значение2)Функция
NULLIF выдаёт значение NULL, если значение1 равно значение2; в противном случае она возвращает значение1. Это может быть полезно для реализации обратной операции к COALESCE. В частности, для примера, показанного выше:SELECT NULLIF(value, '(none)') ...В данном примере если
value равно (none), выдаётся null, а иначе возвращается значение value.То есть в примере выше можно переписать короче и понятнее:
, NULLIF(sdate, '1900-01-01') sdate
, NULLIF(mdate, '1900-01-01') mdate
#PostgreSQL
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🔥5❤4
🌐 openHalo позволяет приложениям, написанным для MySQL, работать с PostgreSQL, предлагая при этом лучшую производительность, чем MySQL!
openHalo поддерживает диалект SQL MySQL и использует тот же протокол соединения, что позволяет легко адаптировать приложения с MySQL к openHalo с минимальными изменениями кода. Это значительно упрощает миграцию с MySQL 5.7 или новее на openHalo, делая процесс быстрее, безопаснее и экономичнее.
С openHalo вы получаете повышенную производительность без дополнительных усилий и затрат, особенно для сложных SQL-запросов. Вы можете продолжать использовать знакомые инструменты, команды и драйверы MySQL для разработки.
🔗 GitHub
#openHalo #MySQL #PostgreSQL #database #migration
@sqlhub
openHalo поддерживает диалект SQL MySQL и использует тот же протокол соединения, что позволяет легко адаптировать приложения с MySQL к openHalo с минимальными изменениями кода. Это значительно упрощает миграцию с MySQL 5.7 или новее на openHalo, делая процесс быстрее, безопаснее и экономичнее.
С openHalo вы получаете повышенную производительность без дополнительных усилий и затрат, особенно для сложных SQL-запросов. Вы можете продолжать использовать знакомые инструменты, команды и драйверы MySQL для разработки.
🔗 GitHub
#openHalo #MySQL #PostgreSQL #database #migration
@sqlhub
❤6🔥5👍2
Возможности
- Прослушивание изменений в PostgreSQL в режиме реального времени.
- Поддержка нескольких слотов репликации.
- Удобный вывод в формате JSON.
- Готов к использованию в качестве сервиса.
Пример использования
1. Создаём слот репликации:
SELECT * FROM pg_create_logical_replication_slot('test_slot', 'wal2json');
2. Запускаем wal-listener:
wal-listener --dsn "host=localhost port=5432 user=postgres dbname=test" --slot test_slot
3. Получаем JSON-объекты при изменениях в базе данных.
https://github.com/ihippik/wal-listener
#devops #девопс #PostgreSQL #sql
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5❤2
🧠 SQL-задача с подвохом: "Невидимые дубликаты"
В таблице
🎯 Цель:
Найти количество уникальных пользователей, если:
- Регистр не учитывается (`alice` = `ALICE`)
- Пробелы игнорируются
- Для
— Убираются точки в имени
— Всё после
✅ SQL-решение:
🔍 Как это работает:
LOWER(TRIM(email)) — убираем пробелы и регистр
SPLIT_PART(..., '+', 1) — отрезаем всё после +
REGEXP_REPLACE(..., '\.', '', 'g') — удаляем точки
Считаем DISTINCT, чтобы получить число уникальных email'ов
🔥 Используй такие трюки для:
• антифрода
• чистки базы
• аналитики поведения пользователей
#SQL #PostgreSQL #Gmail #EmailNormalization #DevTools #AntiFraud #DataCleaning #Analytics
В таблице
users хранятся email-адреса пользователей. Некоторые юзеры регистрируются повторно, маскируя один и тот же email по-разному:| id | name | email |
|----|----------|--------------------------|
| 1 | Alice | [email protected] |
| 2 | Bob | [email protected] |
| 3 | Charlie | [email protected] |
| 4 | Dave | [email protected] |
| 5 | Eve | [email protected] |
🎯 Цель:
Найти количество уникальных пользователей, если:
- Регистр не учитывается (`alice` = `ALICE`)
- Пробелы игнорируются
- Для
@gmail.com: — Убираются точки в имени
— Всё после
+ отрезается✅ SQL-решение:
SELECT COUNT(DISTINCT normalized_email) AS unique_users
FROM (
SELECT
CASE
WHEN email ILIKE '%@gmail.com' THEN
REGEXP_REPLACE(
SPLIT_PART(SPLIT_PART(LOWER(TRIM(email)), '+', 1), '@', 1),
'\.', '', 'g'
) || '@gmail.com'
ELSE
LOWER(REPLACE(TRIM(email), ' ', ''))
END AS normalized_email
FROM users
) AS cleaned;
🔍 Как это работает:
LOWER(TRIM(email)) — убираем пробелы и регистр
SPLIT_PART(..., '+', 1) — отрезаем всё после +
REGEXP_REPLACE(..., '\.', '', 'g') — удаляем точки
Считаем DISTINCT, чтобы получить число уникальных email'ов
🔥 Используй такие трюки для:
• антифрода
• чистки базы
• аналитики поведения пользователей
#SQL #PostgreSQL #Gmail #EmailNormalization #DevTools #AntiFraud #DataCleaning #Analytics
👍10❤4
📦 Outbox — надёжная реализация outbox-паттерна на Go для микросервисов
Если твои сервисы пишут в базу и одновременно публикуют события в Kafka, RabbitMQ или другие брокеры — знай: без outbox-паттерна ты рискуешь потерять данные.
🔧
🧠 Что она делает:
1. Сохраняет событие в таблицу
2. Отдельный воркер читает сообщения и отправляет их в брокер
3. После успешной доставки — сообщение помечается как доставленное
💡 Особенности:
- Поддержка PostgreSQL
- Готовые адаптеры для Kafka и RabbitMQ
- Возможность использовать свой брокер (реализуй интерфейс)
- Поддержка сериализации / форматирования событий
- Использует
🧩 Подходит для:
- надёжной синхронизации БД ↔ событий
- микросервисов, где важна консистентность
- систем, где нужна повторная доставка без дублей
🔥 Отличный выбор, если ты хочешь atomic-публикацию событий без тяжёлых фреймворков и сервисов.
#Go #OutboxPattern #Kafka #RabbitMQ #Microservices #EventDriven #PostgreSQL
🔗 https://github.com/oagudo/outbox
@sqlhub
Если твои сервисы пишут в базу и одновременно публикуют события в Kafka, RabbitMQ или другие брокеры — знай: без outbox-паттерна ты рискуешь потерять данные.
🔧
Outbox — это лёгкая и удобная библиотека на Go, которая помогает сделать доставку сообщений атомарной и надёжной, без лишней сложности.🧠 Что она делает:
1. Сохраняет событие в таблицу
outbox в рамках транзакции2. Отдельный воркер читает сообщения и отправляет их в брокер
3. После успешной доставки — сообщение помечается как доставленное
💡 Особенности:
- Поддержка PostgreSQL
- Готовые адаптеры для Kafka и RabbitMQ
- Возможность использовать свой брокер (реализуй интерфейс)
- Поддержка сериализации / форматирования событий
- Использует
sqlx и стандартную database/sql🧩 Подходит для:
- надёжной синхронизации БД ↔ событий
- микросервисов, где важна консистентность
- систем, где нужна повторная доставка без дублей
🔥 Отличный выбор, если ты хочешь atomic-публикацию событий без тяжёлых фреймворков и сервисов.
#Go #OutboxPattern #Kafka #RabbitMQ #Microservices #EventDriven #PostgreSQL
🔗 https://github.com/oagudo/outbox
@sqlhub
❤5👍5🔥2
🌊📊 pg_lake: Postgres для Iceberg и хранилищ данных
🚀Основные моменты:
- Создание и модификация таблиц Iceberg с полными транзакционными гарантиями.
- Запрос и импорт данных из файлов в форматах Parquet, CSV, JSON.
- Экспорт результатов запросов обратно в облачные хранилища.
- Поддержка геопространственных форматов через GDAL.
- Использование встроенного типа данных для полуструктурированных данных.
📌 GitHub: https://github.com/Snowflake-Labs/pg_lake
#postgresql
pg_lake позволяет интегрировать файлы Iceberg и хранилищ данных в PostgreSQL, превращая его в полноценную lakehouse-систему. Поддерживает транзакции и быстрые запросы к таблицам Iceberg, а также работу с сырыми данными из облачных хранилищ, таких как S3.🚀Основные моменты:
- Создание и модификация таблиц Iceberg с полными транзакционными гарантиями.
- Запрос и импорт данных из файлов в форматах Parquet, CSV, JSON.
- Экспорт результатов запросов обратно в облачные хранилища.
- Поддержка геопространственных форматов через GDAL.
- Использование встроенного типа данных для полуструктурированных данных.
📌 GitHub: https://github.com/Snowflake-Labs/pg_lake
#postgresql
❤5👍5🔥2
🚀 Новый продвинутый планировщик заданий для PostgreSQL - лучше, чем cron
Если устал от cron и временных триггеров, обрати внимание на pg_timetable:
✅ Сильный: гибкий, надёжный, с богатым функционалом
✅ Легко настраивается, понятен и прозрачен
✅ Позволяет:
• запускать SQL-задачи по расписанию
• отслеживать их статус и history
• обеспечивать graceful restart и защиту от сбоев
Идеален для рабочих баз, сложной логики задач и критичных приложений.
📦 Репозиторий: https://github.com/cybertec-postgresql/pg_timetable
#golang #postgresql #devops #golang
Если устал от cron и временных триггеров, обрати внимание на pg_timetable:
✅ Сильный: гибкий, надёжный, с богатым функционалом
✅ Легко настраивается, понятен и прозрачен
✅ Позволяет:
• запускать SQL-задачи по расписанию
• отслеживать их статус и history
• обеспечивать graceful restart и защиту от сбоев
Идеален для рабочих баз, сложной логики задач и критичных приложений.
📦 Репозиторий: https://github.com/cybertec-postgresql/pg_timetable
#golang #postgresql #devops #golang
👍11❤4🔥2
XiYan-SQL - это open-source решение, позволяющее генерировать, анализировать и выполнять SQL-запросы с использованием больших языковых моделей. Инструмент ориентирован на ускорение исследования данных и автоматизацию рутинных операций, связанных с запросами к базе.
Ключевые возможности:
- Генерация SQL из естественного языка -пользователь формулирует задачу обычными словами, а система преобразует её в корректный SQL-запрос.
- Интерактивная работа с базой данных - запросы можно оперативно уточнять, редактировать и выполнять, получая быстрый цикл обратной связи.
- Поддержка нескольких СУБД - PostgreSQL, MySQL, SQLite и другие.
- 🛠️ Минимальная конфигурация - подходит для анализа данных, прототипирования и облегчения доступа к базе без сложной инфраструктуры.
Преимущества использования:
- Существенно снижает трудоёмкость написания сложных SQL-запросов.
- Упрощает работу аналитикам и разработчикам, которым важно быстро получать корректные результаты.
- Может выступать в роли интерактивного помощника для изучения структуры базы и построения отчётов.
🔗 Репозиторий: github.com/XGenerationLab/XiYan-SQL
@ai_machinelearning_big_data
#sql #llm #ai #opensource #database #datatools #postgresql
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤7👎6🥰1
⚡️ SQL-прием: EXISTS часто лучше, чем COUNT(*) > 0
Если тебе нужно просто проверить, есть ли строки, не заставляй базу считать их все.
Плохо:
База может пройти по всем подходящим строкам, чтобы посчитать количество.
Лучше:
EXISTS останавливается сразу, как только нашел первую подходящую строку. Для больших таблиц это может быть заметно быстрее, особенно если есть индекс по условию:
Если тебе нужен ответ “есть или нет”, используй EXISTS. COUNT(*) оставь для случаев, когда реально нужно точное количество строк.
#sql #postgresql #database #backend
Если тебе нужно просто проверить, есть ли строки, не заставляй базу считать их все.
Плохо:
SELECT COUNT(*) > 0
FROM orders
WHERE user_id = 42;
База может пройти по всем подходящим строкам, чтобы посчитать количество.
Лучше:
SELECT EXISTS (
SELECT 1
FROM orders
WHERE user_id = 42
);
EXISTS останавливается сразу, как только нашел первую подходящую строку. Для больших таблиц это может быть заметно быстрее, особенно если есть индекс по условию:
CREATE INDEX idx_orders_user_id ON orders(user_id);
Если тебе нужен ответ “есть или нет”, используй EXISTS. COUNT(*) оставь для случаев, когда реально нужно точное количество строк.
#sql #postgresql #database #backend
👍11❤8🔥3
Хитрый SQL-совет: осторожнее с `NOT IN`
Кажется, что эти запросы делают одно и то же:
Но если banned_users.user_id содержит хотя бы один NULL, запрос может вернуть ноль строк.
Надёжнее использовать NOT EXISTS:
Причина в трёхзначной логике SQL: сравнение с NULL даёт UNKNOWN, а не TRUE или FALSE.
Правило простое: если подзапрос потенциально возвращает NULL, вместо NOT IN почти всегда выбирайте NOT EXISTS.
#sql #postgresql #database
Кажется, что эти запросы делают одно и то же:
SELECT *
FROM users
WHERE id NOT IN (
SELECT user_id
FROM banned_users
);
Но если banned_users.user_id содержит хотя бы один NULL, запрос может вернуть ноль строк.
Надёжнее использовать NOT EXISTS:
SELECT u.*
FROM users AS u
WHERE NOT EXISTS (
SELECT 1
FROM banned_users AS b
WHERE b.user_id = u.id
);
Причина в трёхзначной логике SQL: сравнение с NULL даёт UNKNOWN, а не TRUE или FALSE.
Правило простое: если подзапрос потенциально возвращает NULL, вместо NOT IN почти всегда выбирайте NOT EXISTS.
#sql #postgresql #database
🔥18👍7❤1🥰1
💡 SQL-трюк: сравнивайте `NULL` без костылей
В PostgreSQL обычное сравнение может неожиданно сломать условие:
Результат:
Потому что
Из-за этого часто пишут громоздкие условия:
Но есть оператор, о котором многие забывают:
Он работает как NULL-safe equality:
Есть и обратный вариант:
Например, удобно искать реально изменившиеся значения:
Если оба
Без этого обычное:
может просто вернуть
Особенно полезно при синхронизации данных, аудите изменений, ETL и UPSERT-логике.
#SQL #PostgreSQL #Database
В PostgreSQL обычное сравнение может неожиданно сломать условие:
SELECT NULL = NULL;
Результат:
NULL
Потому что
NULL означает «неизвестное значение», а не конкретное значение.Из-за этого часто пишут громоздкие условия:
WHERE a = b
OR (a IS NULL AND b IS NULL)
Но есть оператор, о котором многие забывают:
a IS NOT DISTINCT FROM b
Он работает как NULL-safe equality:
SELECT NULL IS NOT DISTINCT FROM NULL; -- true
SELECT 10 IS NOT DISTINCT FROM 10; -- true
SELECT 10 IS NOT DISTINCT FROM NULL; -- false
Есть и обратный вариант:
a IS DISTINCT FROM b
Например, удобно искать реально изменившиеся значения:
SELECT *
FROM old_data o
JOIN new_data n USING (id)
WHERE o.email IS DISTINCT FROM n.email;
Если оба
email = NULL, строка не считается изменённой.Без этого обычное:
o.email <> n.email
может просто вернуть
NULL и пропустить изменение.Особенно полезно при синхронизации данных, аудите изменений, ETL и UPSERT-логике.
#SQL #PostgreSQL #Database
🔥9👍8❤7
⚡️ SQL-приём: `GROUPING SETS` может заменить несколько тяжёлых `GROUP BY` + `UNION ALL`.
Допустим, нужно одновременно получить статистику:
- по стране и городу;
- только по стране;
- общий итог.
Часто пишут так:
Но SQL умеет это нативно:
() означает grand total.
А если нужно понять, настоящий ли NULL лежит в данных или это строка итогов:
вернут 1 для колонок, которые были свернуты агрегированием.
🔥 Особенно полезно для:
OLAP-запросов;
аналитических отчётов;
дашбордов;
многоуровневых итогов;
запросов, где иначе появляется несколько почти одинаковых GROUP BY.
Ещё есть:
ROLLUP строит иерархические итоги, а CUBE - все комбинации измерений.
Если в аналитическом SQL у вас появляется цепочка из GROUP BY + UNION ALL, возможно, вы просто забыли про GROUPING SETS.
#SQL #PostgreSQL #DataEngineering #Analytics
Допустим, нужно одновременно получить статистику:
- по стране и городу;
- только по стране;
- общий итог.
Часто пишут так:
SELECT country, city, SUM(revenue)
FROM sales
GROUP BY country, city
UNION ALL
SELECT country, NULL, SUM(revenue)
FROM sales
GROUP BY country
UNION ALL
SELECT NULL, NULL, SUM(revenue)
FROM sales;
Но SQL умеет это нативно:
SELECT
country,
city,
SUM(revenue) AS revenue
FROM sales
GROUP BY GROUPING SETS (
(country, city),
(country),
()
);
() означает grand total.
А если нужно понять, настоящий ли NULL лежит в данных или это строка итогов:
GROUPING(country)
GROUPING(city)
вернут 1 для колонок, которые были свернуты агрегированием.
🔥 Особенно полезно для:
OLAP-запросов;
аналитических отчётов;
дашбордов;
многоуровневых итогов;
запросов, где иначе появляется несколько почти одинаковых GROUP BY.
Ещё есть:
ROLLUP(...)
CUBE(...)
ROLLUP строит иерархические итоги, а CUBE - все комбинации измерений.
Если в аналитическом SQL у вас появляется цепочка из GROUP BY + UNION ALL, возможно, вы просто забыли про GROUPING SETS.
#SQL #PostgreSQL #DataEngineering #Analytics
❤9👍6🔥6🤔1😱1