🧠 SQL-задача для профи: "Ловушка NULL в подзапросе"
Условие:
Есть две таблицы:
✔️ Задание:
Выведите всех сотрудников, которые работают в неактивных отделах.
Если department_id у сотрудника NULL, таких сотрудников выводить не нужно.
❗️Подводный камень:
Решение, которое интуитивно приходит в голову, не работает правильно:
📉 Почему это ошибка:
Если в departments есть хотя бы одна строка, где is_active = true, но id = NULL, то NOT IN (...) будет сравнивать с NULL, а NULL NOT IN (...) всегда возвращает UNKNOWN, то есть — ничего не вернёт.
✅ Правильное решение:
💡 Почему работает:
JOIN отсекает NULL по department_id сразу.
Фильтр по is_active = false работает без ловушек NULL.
Сотрудники без департамента автоматически исключаются.
🔎 Усложнение для профи:
Что произойдёт, если в таблице departments есть id = NULL, is_active = true?
Ответ: ничего — JOIN по NULL никогда не срабатывает. Но если используете NOT EXISTS, нужно быть осторожным.
🧩 Вывод:
Когда дело касается NOT IN и NULL, всегда проверяйте подзапрос. Лучше переходите на JOIN или NOT EXISTS:
📌 Запомни:
NULL ломает IN / NOT IN, но не ломает JOIN / EXISTS.
➡ SQL Community | Чат
Условие:
Есть две таблицы:
CREATE TABLE employees (
id INT PRIMARY KEY,
name TEXT,
department_id INT
);
CREATE TABLE departments (
id INT PRIMARY KEY,
name TEXT,
is_active BOOLEAN
);
Выведите всех сотрудников, которые работают в неактивных отделах.
Если department_id у сотрудника NULL, таких сотрудников выводить не нужно.
❗️Подводный камень:
Решение, которое интуитивно приходит в голову, не работает правильно:
SELECT *
FROM employees
WHERE department_id NOT IN (
SELECT id FROM departments WHERE is_active = true
);
📉 Почему это ошибка:
Если в departments есть хотя бы одна строка, где is_active = true, но id = NULL, то NOT IN (...) будет сравнивать с NULL, а NULL NOT IN (...) всегда возвращает UNKNOWN, то есть — ничего не вернёт.
✅ Правильное решение:
SELECT e.*
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE d.is_active = false;
💡 Почему работает:
JOIN отсекает NULL по department_id сразу.
Фильтр по is_active = false работает без ловушек NULL.
Сотрудники без департамента автоматически исключаются.
🔎 Усложнение для профи:
Что произойдёт, если в таблице departments есть id = NULL, is_active = true?
Ответ: ничего — JOIN по NULL никогда не срабатывает. Но если используете NOT EXISTS, нужно быть осторожным.
🧩 Вывод:
Когда дело касается NOT IN и NULL, всегда проверяйте подзапрос. Лучше переходите на JOIN или NOT EXISTS:
SELECT e.*
FROM employees e
WHERE EXISTS (
SELECT 1
FROM departments d
WHERE d.id = e.department_id AND d.is_active = false
);
📌 Запомни:
NULL ломает IN / NOT IN, но не ломает JOIN / EXISTS.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥5❤2
🗄️ MyDumper — параллельный бэкап MySQL без головной боли. Этот инструмент делает логические дампы MySQL в 5-10 раз быстрее стандартного mysqldump за счёт многопоточной работы. Данные сохраняются в отдельных файлах для каждой таблицы, а встроенная поддержка регулярных выражений позволяет гибко выбирать, какие базы или таблицы включать в бэкап.
Разработчики интересно реализовали согласованность данных: инструмент сначала блокирует таблицы глобальным read-lock, затем создаёт транзакционные снимки для каждого потока и только потом отпускает блокировки. Для восстановления есть параллельный загрузчик myloader
🤖 GitHub
Разработчики интересно реализовали согласованность данных: инструмент сначала блокирует таблицы глобальным read-lock, затем создаёт транзакционные снимки для каждого потока и только потом отпускает блокировки. Для восстановления есть параллельный загрузчик myloader
🤖 GitHub
❤6👍2
Прописаны все виды команд JOIN, а также их визуал.
Крайне полезная штука — сохраняем.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍27🔥7❤5🏆1
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Курс SQL - от новичка до профи
🔹 Регистрация на сайте Oracle
🔹 Что такое SQL? Какие задачи решают Базы Данных?
🔹 Команды SQL: DML, DDL, DCL, TCL
🔹 Агрегатные функции SQL: MIN | MAX | AVG | SUM | COUNT
🔹 Функция GROUP BY. HAVING vs WHERE
🔹INNER JOIN. LEFT JOIN и другие... В ЧЕМ РАЗНИЦА?
🔹Подзапросы SQL Oracle | Вложенные запросы SQL
🔹Агрегатные оконные функции | Аналитические функции sql: min/max/sum/avg/count
🔹Оконные функции SQL | Аналитические функции row_number / dense_ranka
🔹 Регистрация на сайте Oracle
🔹 Что такое SQL? Какие задачи решают Базы Данных?
🔹 Команды SQL: DML, DDL, DCL, TCL
🔹 Агрегатные функции SQL: MIN | MAX | AVG | SUM | COUNT
🔹 Функция GROUP BY. HAVING vs WHERE
🔹INNER JOIN. LEFT JOIN и другие... В ЧЕМ РАЗНИЦА?
🔹Подзапросы SQL Oracle | Вложенные запросы SQL
🔹Агрегатные оконные функции | Аналитические функции sql: min/max/sum/avg/count
🔹Оконные функции SQL | Аналитические функции row_number / dense_ranka
🔥20👍2🥰1🤨1💊1
🎯 Продвинутый SQL-хак: Эффективный поиск по JSONB в PostgreSQL
Если вы работаете с PostgreSQL и храните данные в формате JSONB, вы наверняка сталкивались с проблемой производительности при запросах по вложенным ключам. Вот практический приём, который реально улучшает эффективность таких запросов.
🔍 Проблема
Выполняя запрос:
— вы полагаетесь на оператор
✅ Решение: Используйте выражения + индекс по выражению
1. Создайте индекс по выражению:
2. Теперь ваш запрос будет использовать индекс:
🚀 Бонус: Ускорение с GIN и
Если вы часто фильтруете по множеству разных JSON-полей:
И используйте операторы
📌 Такой подход отлично масштабируется и значительно снижает нагрузку на базу.
💡 Итог: Индексация по выражениям и правильный выбор оператора (`@>`, `->>`) — ключ к быстрой работе с JSONB в PostgreSQL.
Если вы работаете с PostgreSQL и храните данные в формате JSONB, вы наверняка сталкивались с проблемой производительности при запросах по вложенным ключам. Вот практический приём, который реально улучшает эффективность таких запросов.
🔍 Проблема
Выполняя запрос:
SELECT *
FROM events
WHERE data->'user'->>'email' = 'user@example.com';
— вы полагаетесь на оператор
->> для извлечения значения, но такой запрос не использует индекс, даже если JSONB-колонка проиндексирована.✅ Решение: Используйте выражения + индекс по выражению
1. Создайте индекс по выражению:
CREATE INDEX idx_events_user_email
ON events ((data->'user'->>'email'));
2. Теперь ваш запрос будет использовать индекс:
SELECT *
FROM events
WHERE data->'user'->>'email' = 'user@example.com';
🚀 Бонус: Ускорение с GIN и
jsonb_path_opsЕсли вы часто фильтруете по множеству разных JSON-полей:
CREATE INDEX idx_events_data_gin
ON events USING GIN (data jsonb_path_ops);
И используйте операторы
@> для запросов:
SELECT *
FROM events
WHERE data @> '{"user": {"email": "user@example.com"}}';
📌 Такой подход отлично масштабируется и значительно снижает нагрузку на базу.
💡 Итог: Индексация по выражениям и правильный выбор оператора (`@>`, `->>`) — ключ к быстрой работе с JSONB в PostgreSQL.
👍5❤4🔥3🥰1
⚡️ Почему лучшие разработчики всегда на шаг впереди?
Потому что они знают, где брать настоящие инсайд!
Оставь “программирование в вакууме” в прошлом, выбирай свой стек — подпишись и погружайся в поток идей, лайфхаков и знаний, которые не найдёшь в открытом доступе.
ИИ: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Мл собес t.me/machinelearning_interview
C++ t.me/cpluspluc
Docker: t.me/DevopsDocker
Хакинг: t.me/linuxkalii
МЛ: t.me/machinelearning_ru
Devops: t.me/DevOPSitsec
Data Science: t.me/data_analysis_ml
Javascript: t.me/javascriptv
C#: t.me/csharp_ci
Java: t.me/java_library
Базы данных: t.me/sqlhub
Python собеседования: t.me/python_job_interview
Мобильная разработка: t.me/mobdevelop
Golang: t.me/Golang_google
React: t.me/react_tg
Rust: t.me/rust_code
ИИ: t.me/vistehno
PHP: t.me/phpshka
Android: t.me/android_its
Frontend: t.me/front
Big Data: t.me/bigdatai
МАТЕМАТИКА: t.me/data_math
Kubernets: t.me/kubernetc
Разработка игр: https://t.me/gamedev
Физика: t.me/fizmat
SQL: t.me/databases_tg
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка FRONTEND: https://t.me/addlist/mzMMG3RPZhY2M2Iy
🎓954ГБ ОПЕНСОРС КУРСОВ: @courses
😆ИТ-Мемы: t.me/memes_prog
🇬🇧Английский: t.me/english_forprogrammers
🧠ИИ: t.me/vistehno
🖥 Chatgpt для кода в тг: @Chatgpturbobot
📕Ит-книги: https://t.me/addlist/BkskQciUW_FhNjEy
💼ИТ-вакансии t.me/addlist/_zyy_jQ_QUsyM2Vi
Подпишись, чтобы всегда знать, куда двигаться дальше!
Потому что они знают, где брать настоящие инсайд!
Оставь “программирование в вакууме” в прошлом, выбирай свой стек — подпишись и погружайся в поток идей, лайфхаков и знаний, которые не найдёшь в открытом доступе.
ИИ: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Мл собес t.me/machinelearning_interview
C++ t.me/cpluspluc
Docker: t.me/DevopsDocker
Хакинг: t.me/linuxkalii
МЛ: t.me/machinelearning_ru
Devops: t.me/DevOPSitsec
Data Science: t.me/data_analysis_ml
Javascript: t.me/javascriptv
C#: t.me/csharp_ci
Java: t.me/java_library
Базы данных: t.me/sqlhub
Python собеседования: t.me/python_job_interview
Мобильная разработка: t.me/mobdevelop
Golang: t.me/Golang_google
React: t.me/react_tg
Rust: t.me/rust_code
ИИ: t.me/vistehno
PHP: t.me/phpshka
Android: t.me/android_its
Frontend: t.me/front
Big Data: t.me/bigdatai
МАТЕМАТИКА: t.me/data_math
Kubernets: t.me/kubernetc
Разработка игр: https://t.me/gamedev
Физика: t.me/fizmat
SQL: t.me/databases_tg
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка FRONTEND: https://t.me/addlist/mzMMG3RPZhY2M2Iy
🎓954ГБ ОПЕНСОРС КУРСОВ: @courses
😆ИТ-Мемы: t.me/memes_prog
🇬🇧Английский: t.me/english_forprogrammers
🧠ИИ: t.me/vistehno
📕Ит-книги: https://t.me/addlist/BkskQciUW_FhNjEy
💼ИТ-вакансии t.me/addlist/_zyy_jQ_QUsyM2Vi
Подпишись, чтобы всегда знать, куда двигаться дальше!
Please open Telegram to view this post
VIEW IN TELEGRAM
🤨2❤1👍1💊1
🕸️ Chat4Data — расширение, которое превращает веб-скрапинг в диалог
Вместо кода и настроек — просто говоришь, что хочешь, и AI собирает структурированные данные с сайта.
Что умеет Chat4Data:
🔹 Собирает данные “на слух”
Опиши нужную таблицу или список — AI сам найдёт, распарсит и вставит в таблицу. Не нравится результат? Переспроси. Без кода, без боли.
🔹 Обходит все страницы сам
Автоматически кликает “Следующая”, грузит подгружаемые списки и собирает всё — без твоего участия.
🔹 Запускается за 3 клика
AI сам определяет, какие данные ценные, предлагает их — тебе остаётся только подтвердить. Быстро, как в Telegram-боте.
🔹 Не тратит токены на скрапинг
Анализ страницы — на AI, но сами данные забираются без токенов. В бета-версии дают 1 миллион токенов на другие задачи.
🔹 Скоро: скрапинг подстраниц, интерактив, интеграции...
📎 https://chat4data.ai
#ai #scraping #automation #nocode #tools
Вместо кода и настроек — просто говоришь, что хочешь, и AI собирает структурированные данные с сайта.
Что умеет Chat4Data:
🔹 Собирает данные “на слух”
Опиши нужную таблицу или список — AI сам найдёт, распарсит и вставит в таблицу. Не нравится результат? Переспроси. Без кода, без боли.
🔹 Обходит все страницы сам
Автоматически кликает “Следующая”, грузит подгружаемые списки и собирает всё — без твоего участия.
🔹 Запускается за 3 клика
AI сам определяет, какие данные ценные, предлагает их — тебе остаётся только подтвердить. Быстро, как в Telegram-боте.
🔹 Не тратит токены на скрапинг
Анализ страницы — на AI, но сами данные забираются без токенов. В бета-версии дают 1 миллион токенов на другие задачи.
🔹 Скоро: скрапинг подстраниц, интерактив, интеграции...
📎 https://chat4data.ai
#ai #scraping #automation #nocode #tools
👍3❤2🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥3👍2💊2
Forwarded from Machinelearning
Он выступает прослойкой между вашим агентом (например, LangChain, LlamaIndex, VertexAI) и базой данных, упрощая работу с базой, подключение, управление, безопасность и мониторинг.,
Подходит для разработки AI-агентов, которые могут создавать и управлять в реальными БД.
Особенности:
Если делаете агентов, которые работают с
SQL/PostgreSQL/MySQL — точно стоит попробовать.▪ GitHub: https://github.com/googleapis/genai-toolbox
@ai_machinelearning_big_data
#AI #ML #aiagent #opensource #MCP #databases #genai
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥2🥱1💊1
🧠 SQL-задача для опытных разработчиков
В базе есть таблица заказов:
Задача:
Найти всех клиентов, у которых:
- В любые 3 подряд месяца был хотя бы 1 заказ в каждом месяце,
- и суммарная сумма заказов за эти 3 месяца превысила 10,000.
Дополнительно: вывести customer_id, эти 3 месяца (в формате YYYY-MM), общее число заказов за эти месяцы и сумму.
💡 Разбор подхода:
📆 Сначала агрегируем заказы по customer_id и order_month (например, 2024-06), посчитав кол-во заказов и сумму.
🪜 Пронумеруем месяцы для каждого клиента с помощью DENSE_RANK() или ROW_NUMBER().
🧮 Найдём окна из 3 последовательных месяцев (разница в номере = 2), и для них посчитаем сумму.
🧹 Отфильтруем только те окна, где сумма > 10000 и есть 3 записи подряд.
🧩 Решение (PostgreSQL)
В базе есть таблица заказов:
orders (
order_id INT,
customer_id INT,
order_date DATE,
total_amount DECIMAL
)
Задача:
Найти всех клиентов, у которых:
- В любые 3 подряд месяца был хотя бы 1 заказ в каждом месяце,
- и суммарная сумма заказов за эти 3 месяца превысила 10,000.
Дополнительно: вывести customer_id, эти 3 месяца (в формате YYYY-MM), общее число заказов за эти месяцы и сумму.
💡 Разбор подхода:
📆 Сначала агрегируем заказы по customer_id и order_month (например, 2024-06), посчитав кол-во заказов и сумму.
🪜 Пронумеруем месяцы для каждого клиента с помощью DENSE_RANK() или ROW_NUMBER().
🧮 Найдём окна из 3 последовательных месяцев (разница в номере = 2), и для них посчитаем сумму.
🧹 Отфильтруем только те окна, где сумма > 10000 и есть 3 записи подряд.
🧩 Решение (PostgreSQL)
WITH monthly_orders AS (
SELECT
customer_id,
TO_CHAR(order_date, 'YYYY-MM') AS order_month,
DATE_TRUNC('month', order_date) AS month_start,
COUNT(*) AS order_count,
SUM(total_amount) AS total_sum
FROM orders
GROUP BY customer_id, TO_CHAR(order_date, 'YYYY-MM'), DATE_TRUNC('month', order_date)
),
numbered_months AS (
SELECT
customer_id,
order_month,
month_start,
order_count,
total_sum,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY month_start) AS rn
FROM monthly_orders
),
three_month_windows AS (
SELECT
m1.customer_id,
m1.order_month AS month1,
m2.order_month AS month2,
m3.order_month AS month3,
(m1.total_sum + m2.total_sum + m3.total_sum) AS total_window_sum,
(m1.order_count + m2.order_count + m3.order_count) AS total_orders
FROM numbered_months m1
JOIN numbered_months m2 ON m1.customer_id = m2.customer_id AND m2.rn = m1.rn + 1
JOIN numbered_months m3 ON m1.customer_id = m3.customer_id AND m3.rn = m1.rn + 2
WHERE
m3.month_start - m1.month_start <= INTERVAL '62 days' -- ~2 месяца
)
SELECT
customer_id,
month1,
month2,
month3,
total_orders,
total_window_sum
FROM three_month_windows
WHERE total_window_sum > 10000;
👍6❤5👀4🔥2
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
🔥 Совет дня: быстро посчитать частоту значений в колонке
Часто нужно узнать, сколько раз встречается каждое значение в столбце? Используй
📌 Удобно для:
— подсчёта популярных категорий
— анализа активности пользователей
— агрегации логов
💡 Фишка: добавь
Часто нужно узнать, сколько раз встречается каждое значение в столбце? Используй
GROUP BY + COUNT(*):
SELECT category, COUNT(*) AS freq
FROM products
GROUP BY category
ORDER BY freq DESC;
📌 Удобно для:
— подсчёта популярных категорий
— анализа активности пользователей
— агрегации логов
💡 Фишка: добавь
LIMIT — и получишь топ-N значений:
SELECT user_id, COUNT(*) AS actions
FROM logs
GROUP BY user_id
ORDER BY actions DESC
LIMIT 10;
👍8❤1🔥1