Data Science. SQL hub
По всем вопросам- @workakkk @itchannels_telegram - 🔥лучшие ит-каналы @ai_machinelearning_big_data - Machine learning @pythonl - Python @pythonlbooks- python книги📚 @datascienceiot - ml книги📚 РКН: https://vk.cc/cIi9vo #VRHSZ
Show more📈 Analytical overview of Telegram channel Data Science. SQL hub
Channel Data Science. SQL hub (@sqlhub) in the Russian language segment is an active participant. Currently, the community unites 35 975 subscribers, ranking 3 614 in the Technologies & Applications category and 17 757 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 35 975 subscribers.
According to the latest data from 05 September, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 94 over the last 30 days and by -6 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 6.31%. Within the first 24 hours after publication, content typically collects 3.35% reactions from the total number of subscribers.
- Post reach: On average, each post receives 2 271 views. Within the first day, a publication typically gains 1 205 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 9.
- Thematic interests: Content is focused on key topics such as sql, индекс, postgres, index, sqlite.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“По всем вопросам- @workakkk
@itchannels_telegram - 🔥лучшие ит-каналы
@ai_machinelearning_big_data - Machine learning
@pythonl - Python
@pythonlbooks- python книги📚
@datascienceiot - ml книги📚
РКН: https://vk.cc/cIi9vo
#VRHSZ”
Thanks to the high frequency of updates (latest data received on 06 September, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
JOIN, IN, LIKE, BETWEEN, ORDER BY, а также много всего ещё
Пользуйтесь)
@sqlhubconcurrently control. При том, не только в БД, а везде где хоть что-то выполняется параллельно.
Допустим есть пользователь, у него есть 100 денег на счету. Пользователь может их тратить, вы проверяете баланс SELECT balance ..., затем обновляете баланс при покупке UPDATE ... SET balance = ? WHERE .... И вот в счастливый день как-то так вышло, что приходят сразу 2 запроса на покупки для этого пользователя. Одна на 50 денег, вторая на 70. Одна из них должна быть отклонена, т.к. денег недостаточно. Но в результате получается что обе покупки прошли и у вас проблема, вы продали то, что не надо было. И это даже не видно по балансу пользователя. Как же?
Это типичный race condition, обе транзакции сначала данные читают, потом локально что-то делают, потом что-то пишут.
⏩читать им никто не мешает, потому обе транзакции прочитали что у пользователя 100 денег
⏩обе транзакции закономерно решили что денег достаточно
⏩обе транзакции обновили баланс пользователя
При конкурентном доступе к ресурсу подрались только на последнем шаге, транзакция которая начала обновлять данные позже сначала подождала завершение первой транзакции. А затем банально перезаписала баланс на тот который считала правильным сама — lost update аномалия.
▶️Вот как раз для того чтобы предупредить СУБД о том, что мы планируем с данными что-то делать, а потому нам надо сериализовать транзакции иначе, и существует FOR SHARE, FOR UPDATE дополнения. Потому они кстати и задокументированы в разделе Explicit Locking
📎 Подробнее прочитать можно тут
@sqlhubLOWER(DATENAME(month, @Tdate)), однако в таком случае получается месяц в именительном падеже - "май".
И тут полезно вспомнить, что форматирование даты с правильными склонениями месяца работает из коробки:
SELECT FORMAT(GETDATE(), 'dd MMMM yyyy', 'ru-RU')
-- 30 мая 2099
@sqlhubBYTE и CHAR зависит от кодировки и объема данных, которые вы собираетесь представлять в байтах.
⏩BYTE фиксирует объем данных в байтах и идеален для однобайтовых кодировок, таких как ASCII где каждому символу соответствует один байт. Так, VARCHAR2(10 BYTE) вмещает любую комбинацию из десяти байтов.
⏩CHAR же определяет количество символов, не учитывая их объем в байтах; выбрав VARCHAR2(10 CHAR), вы гарантируете пространство на 10 символов, независимо от их размера в байтах. Для иллюстрации вот простой SQL-пример:
-- BYTE: сохраняет байты
CREATE TABLE bytewise (name VARCHAR2(10 BYTE));
-- CHAR: распределяет пространство с учетом количества символов
CREATE TABLE charwise (name VARCHAR2(10 CHAR));
Если BYTE обеспечивает компактность данных, то CHAR гарантирует гибкость, позволяя сохранять символы различной ширины. Ваш выбор зависит от типов символов, которые вы планируете использовать.
Детали при работе с UTF-8
Важно понимать последствия выбора типа данных при работе с многобайтовыми символами кодировки, такой как UTF-8, где один символ может занимать до 4 байтов.
⏩Если вы опираетесь на BYTE, это может привести к проблемам в системах, поддерживающих много языков.
⏩Для предотвращения потери или обрезки данных CHAR будет более надежной опцией, так как он обеспечивает достаточное пространство для любого символа, независимо от его веса.
Критерии для выбора между BYTE и CHAR:
⏩Однородность данных: Если данные подчиняются стандартному размеру в байтах, особенно в случаях, когда важно экономить место, BYTE будет наилучшим выбором.
⏩Многоязычная поддержка: CHAR выигрывает, когда важна поддержка множества языков, это помогает предотвратить проблемы с несоответствием размера хранения.
⏩Производительность: BYTE может быть быстрее по сравнению с CHAR из-за обработки меньшего объема данных, что делает его подходящим для приложений с высокими требованиями к производительности.
📎 Подробнее про BYTE и CHAR можно прочитать тут
@sqlhubDISTINCT
⏩Добавлена возможность для агрегатов, имеющих ORDER BY или DISTINCT, использовать предварительно отсортированные данные
⏩Разрешена мемоизация в UNION ALL
⏩Разрешено выполнять anti-join с ненулевым входом в качестве внутреннего отношения
⏩Разрешено распараллеливание FULL и RIGHT OUTER хэш-соединения
⏩Разрешено оконным функциям использовать более быстрый режим ROWS, когда режим RANGE активен, но не нужен
⏩Оптимизация постоянно увеличивающихся оконных функций ntile(), cume_dist() и percent_rank()
⏩Разрешено удаление left join и unique joins в секционированных таблицах
⏩Можно использовать Limit вместо Unique для реализации DISTINCT, когда это возможно
⏩Ослаблены слишком строгие правила в select_outer_pathkeys_for_merge()
📎 Статья с подробным описанием улучшений
@sqlhubEXISTS:
IF EXISTS (SELECT 1 FROM ваша_таблица WHERE ваш_столбец = ваше_значение)
PRINT 'Запись существует';
ELSE
PRINT 'Запись не найдена';
Замените ваша_таблица, ваш_столбец и ваше_значение релевантными данными. Этот способ является эффективным для поиска записей.
*️⃣Использование SELECT COUNT(*) для проверки наличия записи может показаться удобным, однако это не всегда эффективный подход, особенно при работе с обширными базами данных.
В MS SQL Server целесообразно использовать SELECT TOP 1 для сохранения ресурсов:
IF EXISTS (SELECT TOP 1 1 FROM ваша_таблица WHERE ваш_столбец = ваше_значение)
PRINT 'Запись существует';
В MySQL и PostgreSQL применяйте LIMIT 1 для ограничения выборки:
SELECT 1 FROM ваша_таблица WHERE ваш_столбец = ваше_значение LIMIT 1;
Такие запросы быстро останавливают выполнение, как только найдено первое соответствие.
*️⃣Миф о SELECT COUNT(*). Несмотря на то что многие СУБД оптимизируют SELECT COUNT(*), в работе не все из них показывают одинаковую эффективность. В случае сомнений используйте EXISTS или LIMIT/TOP.
@sqlhubSELECT * FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE region = 'West');
Переписан с использованием JOIN:
SELECT e.* FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id
WHERE d.region = 'West';
Общие табличные выражения (CTE) предоставляют удобный способ упростить сложные запросы и улучшить их читаемость:
WITH RecursiveCTE AS (
SELECT employee_id, first_name, manager_id, 0 AS depth
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.employee_id, e.first_name, e.manager_id, rc.depth + 1
FROM employees e
INNER JOIN RecursiveCTE rc ON e.manager_id = rc.employee_id
)
SELECT * FROM RecursiveCTE;
➖ Более подробно можно прочитать тут
@sqlhubcoalesce("Фамилия", '') || ' ' || coalesce("Имя", '') || ' ' || coalesce("Отчество", '')
Понятно, что тут хотели обезопасить себя от заполненности любого из полей NULL-значением, чтобы случайно вся строка не заNULL'илась.
Правда, тут возникают некоторые артефакты в виде "висящих пробелов" типа ' Иван Иванович' или 'Иванов Иван '.
Но ведь есть решение изящнее и проще - функция concat_ws:
concat_ws(' ', "Фамилия", "Имя", "Отчество")
RTFM!
@sqlhubtextual. Он предлагает дружелюбный интерфейс для интерактивной работы с регулярными выражениями.
▪ Поддерживает оценку регулярных выражений в режимах match или finditer.
▪Предлагает мгновенную обратную связь по результатам сопоставления или поиска.
▪Github
@sqlhubDELETE FROM your_table
WHERE rowid NOT IN (
SELECT MAX(rowid)
FROM your_table
GROUP BY column1, column2, ...
);
2️⃣Удаляем строки с NULL-значениями
DELETE FROM your_table
WHERE column1 IS NULL OR column2 IS NULL;
3️⃣Заменяем NULL-значения на дефолтное выражение
UPDATE your_table
SET column1 = 'default_value'
WHERE column1 IS NULL;
4️⃣Переводим текст в верхний регистр
UPDATE your_table
SET column1 = UPPER(column1);
5️⃣Обрезаем лишнее
UPDATE your_table
SET column1 = TRIM(column1);
6️⃣Конвертируем строки в формат дат
UPDATE your_table
SET date_column = TO_DATE(date_string, 'YYYY-MM-DD');
7️⃣Извлекаем год/месяц/день
SELECT EXTRACT(YEAR FROM date_column) AS year,
EXTRACT(MONTH FROM date_column) AS month,
EXTRACT(DAY FROM date_column) AS day
FROM your_table;
Эти запросы могут помочь вам привести датасет в порядок, используйте)
@sqlhub