SQL Portal | Базы Данных
14.2K subscribers
910 photos
124 videos
49 files
703 links
Присоединяйтесь к нашему каналу и погрузитесь в мир баз данных

Связь: @devmangx

РКН: https://clck.ru/3H4Wo3
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
База данных имеет право выполнять части SQL-выражения WHERE в любом порядке.

Так как же избежать ошибок, если известно, что выражение может выбросить ошибку,

например, извлечение квадратного корня из отрицательного числа?

Используй CASE, чтобы выполнять вычисление только для допустимых значений:

WHERE CASE 
WHEN col > 0 THEN SQRT(col)
ELSE ...
END ...


👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
Шпаргалка по SQL для пользователей SQL Server

1. Типы данных:

Точные числа: int, decimal, money, и т. д.
Приблизительные числа: float, real
Дата и время: datetime, timestamp
Строки char, varchar, text и Unicode версии

2. Функции работы с датой: GETDATE(), YEAR(), DATEADD(), DATEDIFF() и др.

3. Функции работы со строками: LEN(), LEFT(), RIGHT(), REPLACE(), SUBSTRING(), UPPER(), LOWER()

4. Математические функции: ABS(), ROUND(), CEILING(), FLOOR(), POWER(), SQRT()

5. Агрегатные функции: SUM(), AVG(), MAX(), MIN(), COUNT()

6. Создание объектов базы данных:

Хранимые процедуры: CREATE PROCEDURE
Триггеры: CREATE TRIGGER
Представления (view): CREATE VIEW
Индексы: CREATE INDEX
Функции: CREATE FUNCTION

7. Конвертация типов: CAST(), CONVERT()

8. Ранжирование и оконные функции: RANK(), DENSE_RANK(), ROW_NUMBER()

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Если ты новичок в SQL — это просто находка

Это сайт, который анимирует выполнение SQL-запросов.

Ты вставляешь SQL, жмёшь visualize — и видишь, как твой запрос "оживает": шаг за шагом показывает, как SELECT вытягивает данные, как JOIN соединяет таблицы, как фильтруются строки и т.д.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Запросы к графам в Postgres 19 — это начало пути, а не конечная точка.

Postgres использует прагматичный, поэтапный подход к добавлению функциональности. Например, ещё в 2012 году Postgres добавил первую поддержку JSON.

Craig Kerstiens заявил: «мы жульничали», потому что это было просто текстовое поле с наложенной валидацией JSON. Два года спустя был выпущен JSONB. В новых релизах продолжают добавляться дополнительные возможности индексации и операторы. Сейчас и JSON, и JSONB имеют своё место.

Мы ожидаем, что реализация SQL/PGQ в Postgres 19 будет аналогичной. Первоначальный релиз, скорее всего, не заменит существующие рабочие процессы. Он ограничен запросами фиксированной глубины, что уже достаточно просто реализуется с текущим SQL.

Но с чего-то же нужно начинать!

Что реализовано?

DDL-определение: граф объявляется и получает имя.
CREATE PROPERTY GRAPH org_graph указывает, какие таблицы являются вершинами и рёбрами, один раз. Запросы могут ссылаться на граф по имени. Изменения схемы распространяются автоматически, выдаются понятные ошибки, если запрос ссылается на вершину/ребро, которого больше нет, и нельзя удалять таблицы с связанными графами.

Когда-нибудь писали большой CTE-запрос, который сломался из-за изменения схемы? Да, я тоже.

Синтаксис запросов: синтаксис соответствует стандарту SQL:2023. Например, (a)<-[IS reports_to]-(b) означает, что b подчиняется a.

Вы получаете стандартную компонуемость SQL, потому что GRAPH_TABLE ведёт себя как таблица. Его можно джойнить, фильтровать, агрегировать, помещать в CTE и использовать как новый источник в FROM.
Реализованный подход отвечает на вопрос: «Что можно построить минимально, чтобы уже начать работать?» Ответ, судя по всему, — поддержка DDL и поддерживаемый синтаксис запросов.

Что SQL/PGQ пока не умеет, а рекурсивные CTE делают лучше:

Переменная глубина: если нужны все потомки на любой глубине, SQL/PGQ в Postgres 19 поддерживает только фиксированную глубину. Каждое “прыжковое” соединение нужно явно прописывать, что требует знать максимальную глубину на этапе написания запроса и делает запрос длинным.

Агрегация вдоль пути: CTE умеют накапливать массивы, конкатенировать пути, вычислять промежуточные суммы во время рекурсии.

Как и с поддержкой JSON, просто подождите: через несколько релизов вы оглянетесь и скажете: «О, теперь это тоже можно делать».

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
В Oracle AI Database 26ai можно проверять сходство строк с помощью функции:

FUZZY_MATCH(<algo>, <str1>, <str2>)


По умолчанию результат масштабируется от 0 до 100 (0 — нет совпадения, 100 — полное совпадение).

Доступные алгоритмы:
Levenshtein
Jaro-Winkler
Bigram/Trigram
Longest common substring

Попробовать можно прямо на FreeSQL

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Давайте разберём логическую репликацию Postgres с помощью pg_recvlogical. Это CLI-инструмент, который поставляется вместе с Postgres и позволяет стримить изменения логической репликации в stdout. Это простой способ понять, какие данные доступны через логическую репликацию, чтобы вы могли строить свои собственные пайплайны «прямо из Postgres».

Небольшое предупреждение: это демонстрационный пример. В продакшене лучше использовать более надёжный CDC-инструмент, который умеет обрабатывать повторы, обеспечивать устойчивость, эволюцию схем и т.д. Но pg_recvlogical отлично подходит, чтобы увидеть сам механизм в действии. Также мы собираемся выполнить команды, которые изменяют базу данных. Убедитесь, что у вас тестовая база, а не продакшен, или используйте Docker, чтобы поднять временный экземпляр Postgres.

Теперь к коду:
Чтобы запустить Docker Postgres, готовый к логической репликации, сделайте следующее:
Запустите Postgres в Docker-контейнере с wal_level=logical:

docker run --name pg-test -e POSTGRES_PASSWORD=secret -d -p 5432:5432 postgres:latest -c wal_level=logical


Подключитесь к базе (пароль — secret) и создайте базу, таблицу и репликационные слоты:

docker exec -it pg-test createdb -U postgres mydb
docker exec -it pg-test psql -U postgres mydb
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
product TEXT,
quantity INTEGER
);

SELECT pg_create_logical_replication_slot('my_slot', 'test_decoding');


В другом терминале запустите pg_recvlogical, чтобы стримить изменения:

docker exec -it pg-test pg_recvlogical -U postgres -d mydb --slot=my_slot --start -f -


В терминале, где вы подключены к mydb, вставляйте и обновляйте данные. Выполняйте каждую команду по очереди и наблюдайте поток изменений от pg_recvlogical:

INSERT INTO orders (id, product, quantity) VALUES (1, 'Widget', 3);
UPDATE orders SET quantity = 4 WHERE id = 1;
DELETE FROM orders WHERE id = 1;


Вы увидите изменения в реальном времени:

BEGIN 742
table public.orders: INSERT: id[integer]:1 product[text]:'Widget' quantity[integer]:3
table public.orders: UPDATE: id[integer]:1 product[text]:'Widget' quantity[integer]:4
table public.orders: DELETE: id[integer]:1
COMMIT 742


Это, по сути, то, как работают все CDC-инструменты «под капотом»: они подключаются к логическому репликационному слоту и декодируют изменения WAL в поток событий. Конечно, для продакшен-пайплайнов нужно больше — обработка ошибок, повторы, устойчивость, эволюция схем и т.д., но это и есть основной механизм.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
3
This media is not supported in your browser
VIEW IN TELEGRAM
MICROSOFT отказала одному парню — и он на вайб-кодинге собрал свой Excel
Подался в Microsoft, получил отказ и решил с нуля написать терминальный просмотрщик таблиц.

Что он умеет:
- открывает и рендерит .xlsx и .csv прямо в терминале
- навигация полностью с клавиатуры — мышка не нужна
- работает с большими датасетами без лагов, которыми страдает современный Excel
- форматирование ячеек, формулы и сортировка работают прямо в CLI
- достаточно лёгкий, чтобы мгновенно запускаться почти на любой машине

Без ribbon-интерфейса, без раздутого UI, без веб-версии, которая грузится по 10 секунд.
Просто быстрый инструмент для таблиц, который выглядит как софт из 80-х, но работает лучше большинства современных альтернатив.

Первый пользователь — аналитик данных — сказал, что уже много лет считает переход на ribbon-интерфейс ударом по хардкорным пользователям.

Другой пользователь написал, что проект напоминает Lotus 1-2-3 времён DOS, только намного современнее.
Современный Excel — это 90% функций, которыми никто не пользуется, и 10% того, что действительно нужно опытным пользователям.

Этот парень выкинул всё лишнее, оставил только эти 10% и сделал всё быстрым.

https://github.com/bgreenwell/xleak

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁4
Подготовленные выражения и подготовленные транзакции — это полностью разные возможности Postgres, которые совпадают только по слову в названии. Одна используется широко и безопасна. Вторая применяется редко и при неправильном управлении может приводить к простоям.

Начнём с безопасной:
Подготовленные выражения (PREPARE / EXECUTE)

Часто используемая функция оптимизации запросов. SQL-выражение парсится один раз, затем выполняется много раз с разными параметрами. Снижает накладные расходы на парсинг и иногда на построение плана выполнения:

PREPARE find_user (text) AS 
SELECT * FROM users WHERE email = $1;

EXECUTE find_user('alice@example.com');
EXECUTE find_user('bob@example.com');

DEALLOCATE find_user;


• Живёт в пределах одной сессии
• Хранится в памяти, без долговременного хранения
• Безопасно при «забывании»
• Видно через SELECT * FROM pg_prepared_statements
• Используется большинством фреймворков, ORM и библиотек для оптимизации
Подготовленные транзакции (PREPARE TRANSACTION / COMMIT PREPARED)
Большинству приложений эта функциональность не нужна.
Это реализация Postgres двухфазного коммита (2PC / XA транзакции). Транзакция переводится в состояние «готова к фиксации», фиксируется на диске, а завершение выполняется позже из другой сессии:

BEGIN;
INSERT INTO orders VALUES (1, 'widget', 99);
PREPARE TRANSACTION 'order_txn_abc123';

-- позже
COMMIT PREPARED 'order_txn_abc123';
-- или: ROLLBACK PREPARED 'order_txn_abc123';


• Переживает падения и перезапуски (запись в pg_twophase/ внутри каталога)
• Держит блокировки до завершения
• Удерживает идентификатор транзакции (XID) и блокирует автоочистку (vacuum)
• Блокирует DDL-операции над затронутыми таблицами
• Требует max_prepared_transactions > 0 (по умолчанию 0 — одно из удачных значений по умолчанию)

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
SQL-Translator – визуализируй SQL-запросы мгновенно!

Устал разбираться в сложных SQL-запросах? SQL-Translator преобразует их в наглядные схемы, помогая быстро понять структуру данных

🟡 Парсит SQL-запросы и визуализирует их
🟡 Поддерживает PostgreSQL, MySQL, SQLite и другие БД
🟡 Работает прямо в браузере – ничего устанавливать не нужно!

Попробуй сам: здесь

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Ожидается, что в Postgres 19 появится новое contrib-расширение pg_plan_advice, которое добавит пользовательские хинты. Но как Postgres столько лет обходился без хинтов, пока другие СУБД на них опирались? Статистика.

Начиная с 1998 года, Postgres использует статистику на уровне колонок для генерации планов запросов. Алгоритм много раз улучшался и давно считается хорошо проверенной системой выбора плана выполнения на основе статистики. Статистика, которую генерирует ANALYZE, — основа планировщика запросов.
Когда вы запускаете ANALYZE, Postgres строит две структуры для каждой колонки. Именно на них в первую очередь смотрит планировщик, когда оценивает, сколько строк вернёт WHERE.

Ниже примеры из таблицы с HTTP-запросами. Такой набор данных удобно использовать, потому что там есть разные типы значений, которые легко представить.
Список наиболее частых значений (MCV)

Если самая сложная задача в компьютерных науках — кеширование и нейминг, то список most common values заслуживает место в зале славы за удачное название.

Это самые частые значения колонки и их точные частоты:
most_common_vals  = {GET, POST, PUT, DELETE, PATCH}
most_common_freqs = {0.70, 0.20, 0.05, 0.03, 0.02}


Здесь это HTTP-методы, поэтому набор значений ограничен спецификацией.
Для WHERE method = 'GET' планировщик напрямую читает 0.70 из списка.
70% от 200 000 строк = ожидаемые 140 000 строк.
Гистограмма с бакетами равной высоты

Для значений, которых нет в MCV-списке, Postgres строит equi-height buckets. Ниже пример гистограммы для колонки со временем ответа в миллисекундах:
histogram_bounds = {83, 88, 95, 107, 132, 166, 195, 245, 362, 554, 965, 2622164}

Каждый бакет содержит примерно одинаковое количество строк. Бакет [245, 362] содержит примерно столько же строк, сколько [83, 88].

За счёт фиксированного количества строк диапазон значений становится переменным. Это упрощает оценку количества строк.
NULL-гистограммы

Когда все уникальные значения помещаются в MCV-список, histogram_bounds становится NULL.
У колонки method всего 5 значений. Все они попадают в MCV-список, поэтому гистограмма не нужна.

Зачем нужны две структуры?
MCV даёт точные частоты для популярных значений, а гистограмма покрывает длинный хвост — редкие или непрерывные значения через приближение. Вместе они описывают полное распределение без хранения каждого значения отдельно.

Чтобы посмотреть статистику для таблицы и колонки:

SELECT 
most_common_vals,
most_common_freqs,
histogram_bounds
FROM pg_stats
WHERE tablename = 'requests'
AND attname = 'status_code';


👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Кто-то только что выложил в open-source проект, который тихо ломает стандартную модель ценообразования в ИИ.

800 млн токенов инференса в месяц бесплатно.

14 провайдеров. Один унифицированный эндпоинт. Локальный запуск.

Без подписок. Без платных стен. Без “обновите тариф, чтобы продолжить”. Без привязки к одному вендору и экосистеме.

Это не просто более дешёвый доступ к ИИ — это штука, которая заставляет пересмотреть сам факт того, почему базовый инференс вообще был платным.

Это выглядит не как релиз продукта, а как сдвиг в том, как должен работать доступ к ИИ.

Репозиторий👇

https://github.com/tashfeenahmed/freellmapi

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
2
SQL-запросы могут сортировать по невыбранным колонкам, например:
SELECT a FROM t ORDER BY b


Но так было не всегда!

Markus Winand проводит обзор истории ORDER BY, рассматривая:
- позиционные ссылки (positional references)
- невыбранные колонки (non-selected columns)
- выражения (expressions)
- порядок сортировки NULL-значений (null ordering)
- подзапросы (subqueries)

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Парень создал систему поиска работы при помощи Claude Code

Которая в итоге отправила более 700 заявок и помогла найти работу. 🥳

Он выложил её в опенсорс.

Она автоматизирует весь процесс: сканирует страницы вакансий разных компаний, адаптирует твоё резюме под каждую конкретную позицию и даже автоматически заполняет формы за тебя. В репозитории есть:

- 14 различных режимов (оценка, парсинг, PDF и т.д.)
- терминальный dashboard на Go
- генерация PDF-резюме, оптимизированного под ATS, через Playwright
- уже более 45 настроенных компаний (Anthropic, OpenAI, ElevenLabs, Stripe…)

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Real-Time Dashboard для PostgreSQL прямо в терминале: https://github.com/mujib77/cosmo

Просматривай внутреннее состояние базы данных напрямую: запросы, записи, блокировки и подключения — всё в одном интерфейсе.

TUI для терминала, написанный на Go, который подключается к Postgres и показывает, что происходит внутри базы данных. Он читает системные представления вроде pg_stat_activity и pg_stat_database, обновляя данные каждые две секунды, и в реальном времени отображает метрики: активные запросы, cache hit rate, скорость записи WAL и ожидания блокировок.

Интерфейс разделён на четыре панели:
- Overview
- Queries
- WAL/MVCC
- Locks

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🚫 НИКОГДА не используй COUNT для проверки существования
Если тебе нужно просто проверить, существует ли конкретный элемент в данных, не используй COUNT() с фильтром (WHERE).

SELECT COUNT(*)
FROM users
WHERE email = 'http://thisemaildontexist.com'


Проблема в том, что COUNT(*) отвечает на другой вопрос. Он считает количество строк, которые удовлетворяют условию, хотя тебе нужно только знать, есть ли хотя бы одна.
Когда ты используешь COUNT(*), база данных может просканировать все подходящие строки, чтобы вычислить итог. Даже если она найдёт одно совпадение сразу, она может продолжить работу, потому что ты запросил полный подсчёт. Это лишняя работа при больших таблицах.

Вместо COUNT() используй EXISTS
SELECT EXISTS (
SELECT 1
FROM users
WHERE email = 'http://thisemaildontexist.com'
);


С EXISTS база данных остановится, как только найдёт первое совпадение. Без подсчёта. Без лишнего сканирования.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Чистые данные — это основа надёжной аналитики. SQL упрощает работу с NULL-значениями, дубликатами, выбросами, проблемами форматирования, опечатками и несогласованными значениями перед анализом или построением отчётности. Хорошие навыки очистки данных повышают точность и качество принимаемых решений. #SQL #DataAnalytics #DataCleaning #DataScience

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
Почему запрос
SELECT * FROM users WHERE status <> 'banned';

не возвращает Charlie, если у него status = NULL?

Потому что в SQL NULL означает «неизвестное значение», а не пустую строку и не какое-то конкретное значение.
Когда SQL проверяет условие:

status <> 'banned'

для строки, где:
status = NULL


результат будет не TRUE и не FALSE, а UNKNOWN.
То есть SQL не может определить, равно ли неизвестное значение 'banned' или нет.

Получается:
NULL = 'banned'    → UNKNOWN
NULL <> 'banned' → UNKNOWN


А в секцию WHERE попадают только строки, для которых условие вернуло TRUE.
TRUE     → строка возвращается
FALSE → строка отбрасывается
UNKNOWN → строка тоже отбрасывается


Поэтому Charlie не попадает в результат.
Если нужно включить строки с NULL, условие следует написать так:
SELECT *
FROM users
WHERE status <> 'banned'
OR status IS NULL;


или в некоторых СУБД (например, PostgreSQL):
SELECT *
FROM users
WHERE status IS DISTINCT FROM 'banned';


Этот оператор рассматривает NULL как отдельное значение и вернёт все строки, где статус не 'banned', включая NULL.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Для выполнения ad-hoc-поиска по данным в форматах JSON и XML можно создавать поисковые индексы.

В Oracle AI Database 26ai синтаксис был упрощён до:

CREATE SEARCH INDEX ... ON ... ( { xmlcol | jsoncol } )


Это позволяет выполнять полнотекстовый поиск по значениям XML- и JSON-документов с использованием индекса, что значительно ускоряет запросы по неструктурированным данным.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM