Telegram Group Search
🧠 SQL-задача с подвохом (Oracle)

Тема: оконные функции, группировка, ловушка в агрегатах

📌 Задача:

Есть таблица SALES со следующей структурой:


CREATE TABLE SALES (
ID NUMBER,
REGION VARCHAR2(20),
SALE_DATE DATE,
AMOUNT NUMBER
);


Пример данных:

| ID | REGION | SALE_DATE | AMOUNT |
|----|--------|-----------|--------|
| 1 | North | 01-JAN-24 | 100 |
| 2 | North | 02-JAN-24 | 120 |
| 3 | South | 01-JAN-24 | 90 |
| 4 | South | 03-JAN-24 | 200 |
| 5 | East | 01-JAN-24 | 150 |
| 6 | East | 02-JAN-24 | 100 |


🧩 Найти:
Для каждого региона — ту дату, в которую была вторая по величине сумма продаж.
Если в регионе меньше двух дат — не выводить его вовсе.

🎯 Подвох:
- нельзя использовать LIMIT, FETCH FIRST, QUALIFY и подзапросы с ROWNUM напрямую (нужно решение через оконные функции Oracle)
- многие пытаются взять MAX(AMOUNT) с OFFSET 1, но в Oracle это не так просто

Ожидаемый результат:

| REGION | SALE_DATE | AMOUNT |
|--------|-----------|--------|
| North | 01-JAN-24 | 100 |
| South | 01-JAN-24 | 90 |
| East | 02-JAN-24 | 100 |

🔍 Решение:

```sql
SELECT REGION, SALE_DATE, AMOUNT
FROM (
SELECT
REGION,
SALE_DATE,
AMOUNT,
DENSE_RANK() OVER (PARTITION BY REGION ORDER BY AMOUNT DESC) AS rnk,
COUNT(DISTINCT SALE_DATE) OVER (PARTITION BY REGION) AS cnt
FROM SALES
)
WHERE rnk = 2 AND cnt >= 2;
```

📌 **Объяснение подвоха:**
- `DENSE_RANK` гарантирует, что если есть одинаковые суммы, они получат один и тот же ранг
- `COUNT(DISTINCT SALE_DATE)` проверяет, что у региона хотя бы две разные даты (иначе регион исключается)
- Работает чисто на оконных функциях, без подзапросов с ROWNUM — идеально для Oracle

🧪 Проверь результат и попробуй адаптировать под похожие задачи с TOP-N логикой.

@sqlhub
🧠 SQL-задача с подвохом: “Самый активный — или самый невидимый?”

📘 Условие

У тебя есть две таблицы:


users(id, name)
posts(id, user_id, title)


Вопрос:
Выведи всех пользователей, у которых нет ни одного поста,
а также пользователя, у которого больше всего постов.

📌 Но — в одном запросе.

Попробуй решить задачу таким SQL:


SELECT u.name, COUNT(p.id) AS post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.name
HAVING COUNT(p.id) = 0 OR COUNT(p.id) = (
SELECT MAX(cnt)
FROM (
SELECT COUNT(*) AS cnt
FROM posts
GROUP BY user_id
) t
);


🔍 Вопрос:

1) Почему он может вернуть неправильный результат?
2) В чём разница между COUNT(*) и COUNT(p.id)?
3) Как переписать его правильно?

Разбор подвоха

💣 Подвох 1: COUNT(p.id) пропускает NULL

Когда ты делаешь LEFT JOIN, для пользователей без постов p.id = NULL.

COUNT(*) считает все строки (включая NULL)
COUNT(p.id) не считает строки, где p.id IS NULL

👉 Это может привести к тому, что:
COUNT(p.id) = 0 — действительно "нет постов"
• но в подзапросе SELECT COUNT(*) считает иначе и даёт искаженную MAX(cnt)

🔁 Как правильно:

1) Подзапрос должен использовать COUNT(p.id), чтобы сравнение было честным
2) Либо использовать JOIN вместо LEFT JOIN в подзапросе, чтобы не попасть на "нулевых" пользователей

Финальный корректный запрос:


SELECT u.name, COUNT(p.id) AS post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.name
HAVING COUNT(p.id) = 0
OR COUNT(p.id) = (
SELECT MAX(cnt)
FROM (
SELECT user_id, COUNT(p.id) AS cnt
FROM posts
GROUP BY user_id
) AS ranked
);


🎯 Такой запрос честно покажет:

• Всех “молчунов” (0 постов)
• И самого активного автора (макс постов)

📌 Отлично подходит для собеседования или тех, кто считает, что "GROUP BY — это просто".
@sqlhub
Если вы размышляете, как усилить своё резюме, наш совет — освойте SQL. Это язык, который помогает извлекать ценную информацию из массивов данных.

Познакомиться с инструментом можно на бесплатном курсе «Введение в SQL и работу с базой данных». За 5 занятий вы научитесь создавать, редактировать и обновлять базы данных, сделаете свои первые запросы и отчёты.

Курс будет полезен даже тем, кто пока не собирается становиться аналитиком. Научитесь применять SQL в своих задачах — с ним вы сможете больше – https://netolo.gy

Реклама. ООО "Нетология". ИНН 7726464125 Erid: 2VSb5y1d224
🦦 Walrus — удобная обёртка над Redis для Python-разработчиков. Этот проект расширяет стандартный клиент redis-py, добавляя к нему набор полезных абстракций для работы с Redis.

Вместо того чтобы заставлять изучать новый API, Walrus предлагает привычный интерфейс с дополнительными возможностями. При этом проект остаётся лёгковесным и сохраняет совместимость с альтернативными Redis-подобными базами вроде rlite.

🤖 GitHub

@sqlhub
Изучите секреты самых популярных open source key-value СУБД – Redis и Valkey

В высоко-нагруженных сервисах Redis — не просто кэш, а важная подсистема, на которой строится значимая часть бизнес-логики. От его стабильности, масштабируемости и отказоустойчивости зависит производительность всего сервиса. Valkey - это современный производительный форк Redis с открытым исходным кодом, поддерживаемый сообществом и рядом крупных компаний. Valkey набирает популярность, поддержан крупными облачными провайдерами, и вполне возможно потеснит или вовсе заменит Redis со временем. Наш курс — для тех, кто хочет держать свой стэк и знания актуальными и глубоко разбираться, как устроен Redis и Valkey.

🌐 В программе курса:

🤩 Как эффективно использовать базовые и продвинутые структуры данных: HyperLogLog, Bitmaps и Bisields, Streams, Geospatial-индексы, Bloom Filters
🤩 Как проектировать in-memory системы, которые не разваливаются под нагрузкой, что влияет на отказоустойчивость и как её добиться
🤩 Как работает репликация и кластеризация на практике (режимы Sentinel и Cluster)
🤩 Как встроить Redis/Valkey в реальный прод с учётом безопасности, интеграций и современных практик мониторинга.

🥸 Кто мы: R&D-центр Devhands. Автор курса — Константин Ратвин — преподаватель МФТИ на кафедре БИТ (совместно со СберТех), эксперт по распределённым системам и банковским ИТ, автор курсов по СУБД и инфраструктуре, спикер HighLoad++ и PGConf.

🗓 Старт курса: 9 июня, 6 недель обучения.
Изучить программу и записаться можно здесь.

Ждем вас!

Реклама. ИП Рыбак А.А. ИНН 771407709607 Erid: 2VtzqwXctGc
Please open Telegram to view this post
VIEW IN TELEGRAM
🐘 Slonik — проверенный клиент PostgreSQL для Node.js с строгой типизацией и детальным логированием. Этот инструмент решает проблему безопасности и предсказуемости работы с SQL-запросами: вместо ручного формирования запросов проект заставляет использовать литералы с автоматическим экранированием параметров.

Интересна встроенная интеграция с Zod для валидации результатов запросов, она предотвращает ошибки при изменении схемы БД без обновления кода. Также Slonik умеет логировать стектрейсы вызовов запросов и перезапускать упавшие транзакции.

🤖 GitHub

@sqlhub
👣 Stateless Postgres Query Router — это система шардирования для PostgreSQL-кластера, доступная с открытым исходным кодом. Её основной компонент, роутер, анализирует запросы и определяет, на каком конкретном PostgreSQL-кластере следует выполнить транзакцию или запрос.

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

SPQR поддерживает как запросы к определённому шарду, так и запросы ко всем шардам. В ближайших планах — добавить поддержку двухфазных транзакций и референсных таблиц.

Исходный код SPQR распространяется под лицензией PostgreSQL Global Development Group

⚡️ Ссылки:
🟢https://github.com/pg-sharding/spqr
🟢https://pg-sharding.tech/

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🗂️ BRModelo Web — веб-приложение для проектирования баз данных. Этот open-source проект позволяет создавать ER-диаграммы прямо в браузере с экспортом в SQL-скрипты.

Инструмент имеет образовательную направленность. Интерфейс на португальском и английском языках адаптирован для учебных задач: есть подсветка сущностей, автоматическая расстановка связей и валидация схемы. Запустить локальную копию можно через Node.js + MongoDB или Docker-контейнеры.

🤖 GitHub

@sqlhub
В мире, где данные — это новая валюта, каждый специалист должен уметь работать с ними на высшем уровне. Особенно — аналитики.

Сделать уверенный старт в профессии можно на курсе «Аналитик данных» от karpovꓸcourses. Вы узнаете, как наводить порядок в потоке данных, выявлять скрытые связи, превращать хаотичные цифры в понятные факты и точные решения, которые помогают бизнесу двигаться вперед.

На курсе есть все, что нужно для эффективной работы с данными: от Python и SQL до BI-инструментов и создания дашбордов.

С 12 по 31 мая погружаться в аналитику еще выгоднее. При покупке курса «Аналитик данных» и симулятора A/B-тестов вы получите скидку 10%. А главное, сразу усилите резюме ценными навыками.

Реклама. ООО «Карпов Курсы», ИНН: 7811764627, erid: 2VtzqunnpSp
🐘 pgBackRest — надежное решение для резервного копирования PostgreSQL. В отличие от стандартных утилит, pgBackRest предлагает параллельное выполнение операций, поддержку инкрементных бэкапов на уровне блоков и встроенную проверку целостности через контрольные суммы.

Особого внимания заслуживает гибкость развертывания: резервные копии можно хранить локально, на удаленных серверах через SSH/TLS или в облачных хранилищах S3/Azure/GCS. Система автоматически управляет ротацией архивов и обеспечивает консистентность данных даже при аварийном завершении работы.

🤖 GitHub

@sqlhub
Истории, после которых ты захочешь уволиться

Ты правда думал, что так и будешь сидеть в найме до пенсии?

А потом читаешь пост какого-то чувака из IT и ловишь: “бл*, я тоже так хочу”.

В этом канале бывший дата саентист — Глеб Михайлов. Он уволился из Яндекса, послал всё на*** и теперь пишет как есть:

– про выгорание,
– про деньги, свободу и зашквар,
– и как из всего этого лепить свою жизнь.

Топ постов канала:

👉 7 лет отсидки (https://www.tg-me.com/mikhaylovgleb/336) (в офисе)
👉 Страшно – пи***ц (https://www.tg-me.com/mikhaylovgleb/302)
👉 Робот-пылесос для денег (https://www.tg-me.com/mikhaylovgleb/347)

Подпишись - https://www.tg-me.com/mikhaylovgleb, если тоже устал терпеть.

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


Реклама
🛠️ История создания “storage-agnostic” message queue


Контекст:
Работая на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы.

Основная проблема


Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?

🧱 Как это реализовано в VarMQ

После рефакторинга Gocq был разделён на два компонента:
1) Worker pool — пул воркеров, обрабатывающих задачи
2) Queue interface — абстракция над очередью, не зависящая от реализации

Теперь воркер просто берёт задачи из очереди, не зная, где они хранятся.

🧠 Пример использования

• In-memory очередь:


w := varmq.NewVoidWorker(func(data any) {
// обработка задачи
}, 2)
q := w.BindQueue()


• С SQLite-поддержкой:


import "github.com/goptics/sqliteq"

db := sqliteq.New("test.db")
pq, _ := db.NewQueue("orders")
q := w.WithPersistentQueue(pq)


• С Redis (для распределённой обработки):


import "github.com/goptics/redisq"

rdb := redisq.New("redis://localhost:6379")
pq := rdb.NewDistributedQueue("transactions")
q := w.WithDistributedQueue(pq)


В итоге воркер обрабатывает задачи одинаково — независимо от хранилища.

Почему это круто

• Гибкость: адаптеры позволяют легко менять хранилище без правок воркера
• Минимальные зависимости: в яд

📌 Читать
🧠 Уровень Pro: Медиана, ранги и NULL в Oracle SQL

📋 Есть таблица sales:


CREATE TABLE sales (
salesman_id NUMBER,
region VARCHAR2(50),
amount NUMBER
);


📦 Данные:

| salesman_id | region | amount |
|-------------|------------|--------|
| 101 | 'North' | 200 |
| 101 | 'North' | NULL |
| 102 | 'North' | 150 |
| 103 | 'North' | NULL |
| 104 | 'South' | 300 |
| 105 | 'South' | NULL |
| 106 | 'South' | 50 |
| 107 | 'South' | NULL |


🎯 Задача 2.0:
Вывести salesman_id, чья сумма продаж меньше медианы по региону,
и показать ранг продавца внутри региона по сумме продаж, где NULL = 0.

Подвохи:
- MEDIAN() доступен только в Oracle.
- Нужно предварительно агрегировать суммы.
- Продавцы с только NULL-продажами = 0.
- Ранг должен учитывать правильную сортировку и связи с регионом.

Решение:

```sql
WITH sales_total AS (
SELECT
salesman_id,
region,
NVL(SUM(amount), 0) AS total_sales
FROM sales
GROUP BY salesman_id, region
),
region_median AS (
SELECT
region,
MEDIAN(total_sales) AS region_median
FROM sales_total
GROUP BY region
),
ranked AS (
SELECT
st.salesman_id,
st.region,
st.total_sales,
r.region_median,
RANK() OVER (PARTITION BY st.region ORDER BY st.total_sales DESC) AS sales_rank
FROM sales_total st
JOIN region_median r ON st.region = r.region
)
SELECT *
FROM ranked
WHERE total_sales < region_median;
```

🧠 Объяснение:

1. `sales_total`: агрегируем продажи по продавцу, `NULL → 0`
2. `region_median`: считаем **медиану** продаж по каждому региону
3. `ranked`: добавляем `RANK()` по убыванию продаж внутри региона
4. Финальный фильтр: продажи ниже медианы

🔍 Пример вывода:

| salesman_id | region | total_sales | region_median | sales_rank |
|-------------|--------|-------------|----------------|-------------|
| 105 | South | 0 | 50 | 3 |
| 107 | South | 0 | 50 | 3 |
| 103 | North | 0 | 150 | 3 |

📌 Польза:

Отлично проверяет:
- знание оконных функций
- работу с медианой
- поведение `NULL` в агрегатах
- построение CTE-цепочек и аналитики

🔁 Можно расширить:
- Добавить ранги *по убыванию и по возрастанию*
- Вместо `MEDIAN()` использовать `PERCENTILE_CONT()`
- Построить дэшборд: кто всегда "ниже медианы" за месяц

@sqlhub
🧠 SQL-задача с подвохом: кто на самом деле опоздал?

У тебя есть таблица с логами входа сотрудников в офис. Но задача не в том, чтобы просто найти "кто пришёл позже 9:00", а выяснить кого стоит считать реально опоздавшим, если учесть такую бизнес-логику:

> Сотрудники входят в офис через турникет. Иногда турникет сканирует пропуск с задержкой, а иногда — несколько сотрудников входят подряд. Поэтому, если кто-то зашёл не позже, чем через 2 минуты после своего коллеги из той же команды — его не считают опоздавшим.

📊 Данные


CREATE TABLE office_logs (
employee_id INT,
team_id INT,
entry_time TIMESTAMP
);


Пример данных:

| employee_id | team_id | entry_time |
|-------------|---------|---------------------|
| 1 | 10 | 2024-01-01 08:59:10 |
| 2 | 10 | 2024-01-01 09:00:50 |
| 3 | 10 | 2024-01-01 09:02:20 |
| 4 | 20 | 2024-01-01 09:03:00 |
| 5 | 20 | 2024-01-01 09:04:40 |
| 6 | 20 | 2024-01-01 09:10:00 |


🎯 Задача

Напиши SQL-запрос, который определяет реально опоздавших сотрудников, если:

1. Время входа позже 09:00:00
2. Они не шли следом за коллегой из своей команды (разница входа больше 2 минут)
3. Один и тот же сотрудник не может быть "оправдан" несколькими — ищем только ближайшего предыдущего по времени из своей команды

💡 Подсказка: тут нужны:
- оконные функции (`LAG`)
- фильтрация по team_id
- расчёт интервалов времени
- доп. условия на время и порядок

Реальное мышление аналитика начинается там, где бизнес-логика важнее простых фильтров.


Решение:

```sql
WITH logs_with_prev AS (
SELECT
employee_id,
team_id,
entry_time,
LAG(entry_time) OVER (
PARTITION BY team_id
ORDER BY entry_time
) AS prev_entry_time
FROM office_logs
),
marked_late AS (
SELECT
*,
EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) AS seconds_diff
FROM logs_with_prev
)
SELECT
employee_id,
team_id,
entry_time
FROM marked_late
WHERE
entry_time::time > '09:00:00'
AND (
prev_entry_time IS NULL
OR EXTRACT(EPOCH FROM (entry_time - prev_entry_time)) > 120
);
```

🔍 **Что происходит:**
• Сначала `LAG` находит предыдущего входившего из той же команды
• Затем считаем, сколько секунд прошло между входами
• Если прошло больше 2 минут или сотрудник был первым — он **реально опоздал**

📦 Такое решение пригодится, если нужно учитывать **контекст** и **временные связи**, а не просто жёсткие фильтры.

@sqlhub
SQL_cheatsheet.pdf
754.9 KB
⚡️ SQL-шпаргалка, которая выручит в интервью, проекте и проде

Полный мастер-гайд по SQL в одном PDF: практичные примеры, чёткие объяснения и никакой воды.

Что внутри:
💬 Создание баз, таблиц и изменение схем
💬 Запросы любого уровня сложности: JOIN, GROUP BY, HAVING, PARTITION
💬 Подзапросы, CTE, оконные функции: ROW_NUMBER, RANK, DENSE_RANK
💬 VIEW, временные таблицы и работа с дубликатами
💬 Даты, строки, преобразования и агрегации
💬 Очистка данных, разбиение по разделителям
💬 UNION, INTERSECT, EXCEPT — управление сложными выборками

Затрагиваются и продвинутые кейсы:
• Парсинг адресов
• Кастомная сортировка
• Использование ISNULL и COALESCE

🧠 Это не просто набор команд — это концентрат боевого SQL-опыта.

Подходит для:
➡️ Подготовки к SQL-интервью
➡️ BI и аналитики
➡️ Web-разработки с базами
➡️ Встраивания SQL в проекты на Python, Go, Java и других языках
Media is too big
VIEW IN TELEGRAM
7–8 июня проводим Weekend Offer Analytics

Устроиться в Яндекс за выходные — реально. Ищем крутых аналитиков с опытом работы от 3 лет на Python, готовых работать в офисном или гибридном режиме.

Подавайте заявку до 3 июня — и всего за 2 дня пройдите технические собеседования. После сможете пообщаться с двенадцатью нанимающими командами и выбрать ту, которая покажется самой интересной. Если всё сложится хорошо, сразу же пришлём вам офер.

Узнать подробности и зарегистрироваться.

Реклама. ООО "Яндекс". ИНН 7736207543
🦆 DuckDB теперь дружит с scikit-learn — мощный дуэт для ML-прототипов

В свежем гайде от 16 мая 2025 команда DuckDB показывает, как использовать их аналитическую СУБД вместе с scikit-learn — чтобы максимально быстро и удобно прототипировать модели машинного обучения.

💡 Пример — классификация пингвинов (датасет Palmer Penguins):

🔸 Предобработка в DuckDB:

Удаление NULL-ов, фильтрация, типизация.

Категориальные признаки кодируются через референс-таблицы (вместо LabelEncoder).

Используется selection_query с ленивым выполнением — данные грузятся только при необходимости.

🔸 Интеграция с scikit-learn:

Извлекаем pandas DataFrame прямо из DuckDB.

Обучаем классификатор (например, RandomForestClassifier) по подготовленным данным.

🛠 Идеально для:
• Быстрого прототипирования моделей
• Малых и средних наборов данных
• Python-разработчиков, которым не хочется возиться с SQL-серверами

📎 Подробнее:
https://duckdb.org/2025/05/16/scikit-learn-duckdb.html

@sqlhub
YTsaurus, разработанная в Яндексе платформа для хранения и обработки больших данных, стала доступна как управляемый сервис в Yandex Cloud.

До 2023 года YTsaurus использовалась только внутри компании - для обучения нейросетей, аналитики, обработки телеметрии и работы с поисковым индексом. В прошлом году платформу выложили в опенсорс, и с тех пор она применяется как внутри Яндекса, так и за его пределами.

Теперь YTsaurus можно развернуть в облаке - без ручной настройки и с поддержкой от команды Яндекса. Платформа работает с эксабайтами данных, масштабируется до миллиона CPU и десятков тысяч GPU, поддерживает ClickHouse, Spark, MapReduce и подходит для любых сценариев - от ETL до построения хранилищ.

Заявки на ранний доступ уже открыты.
🚀 Запуск обновленной версии курса «ML для финансового анализа»!

Пройдите полный цикл создания торгового агента: от сбора и очистки данных до переноса в продакшн. Уже через полгода вы сможете самостоятельно разработать торгового бота!

🔹 Новое в программе
- Портфельные стратегии и модели перебалансировки.
- Предсказание цен с LSTM и оценка текстов.
- Ансамбль блендинга с LLM.

🔹 Структура курса
- Пошаговое обучение с домашними заданиями для создания торгового бота.

🔹 Адаптация под ваши запросы
- Синтетические датасеты, свечные графики, очистка данных и многое другое.

🔹 Практический модуль
- Перенос модели в продакшн, облачная инфраструктура, микросервисы и контроль метрик.

🎉 Специальное предложение
Успейте воспользоваться 🏷10% скидкой на курс «ML для финансового анализа» и 🎁 бонусным промокодом FINANCE_5 и учитесь по ценам мая! Выгодные условия действуют по 31 мая включительно.

➡️ Ссылка для регистрации: https://tglink.io/bc637989f23f?erid=2W5zFK19MMi

#реклама
О рекламодателе
🎯 SQL-задача с подвохом для аналитиков

Таблица sales:


CREATE TABLE sales (
id SERIAL PRIMARY KEY,
seller_name VARCHAR,
sale_amount NUMERIC,
sale_date DATE
);


📌 Задача:
Найди имя продавца, который заработал максимальную сумму за каждый месяц.

🧠 Подвох:
Многие пытаются использовать GROUP BY month, seller_name и MAX(), но это не даст имя продавца — только сумму. Нужно вернуть имя лучшего продавца за месяц. А если таких несколько? Тоже учти.

💡 Подсказки:

• Сначала сгруппируй продажи по month и seller_name
• Посчитай SUM(sale_amount)
• Используй оконную функцию RANK() или ROW_NUMBER()
• Отфильтруй только те строки, где rank = 1

🧩 Решение:


WITH monthly_totals AS (
SELECT
DATE_TRUNC('month', sale_date) AS month,
seller_name,
SUM(sale_amount) AS total
FROM sales
GROUP BY 1, 2
),
ranked AS (
SELECT *,
RANK() OVER (PARTITION BY month ORDER BY total DESC) AS rnk
FROM monthly_totals
)
SELECT month, seller_name, total
FROM ranked
WHERE rnk = 1
ORDER BY month;


👀 Бонус-вопрос:
Что будет, если у двух продавцов одинаковая сумма за месяц?
Какой оконной функцией это корректно учесть?

👉 RANK() вернёт обоих, ROW_NUMBER() — только одного.

📌 Отличная задача, чтобы проверить знание оконных функций и работы с агрегацией в SQL.

@sqlhub
2025/05/31 16:47:41
Back to Top
HTML Embed Code: