Pull to refresh

Comments 14

В первом примере ошибка, кмк: DISTINCT во внешнем запросе уберёт однофамильцев. Во внутреннем запросе уже есть DISTINCT по Client_id, для задачи этого достаточно...

Благодарю, тест на внимательность пройден. Исправлю.

Зачем там вообще distinct, в любом месте?

with x (id, smth) as (select 1, 'smth' union all select 2, 'smth else' union all select 3, 'anthr')
, y (id) as (select 1 union all select 2 union all select 1)
select *
from x
where id in (select id from y);

И зачем вообще вариант с IN, если есть с EXISTS.

Кейс 1 ... Этот запрос позволяет быстро выделить тех

Да, запрос позволит их выбрать. Но использованный WHERE IN, тем более в сочетании с DISTINCT, не позволит сделать это быстро. Следует для быстрой обработки следует использовать WHERE EXISTS.

Кейс 2

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

Кейс 5

Та же ситуация, что в первом кейсе. Подзапрос должен быть перемещён или в CTE, или в секцию FROM.

Кейс 6

А тут аж два уровня вложенности подзапросов.

Но это полдела. Тут ещё и с математикой нелады, что для аналитика ну просто-таки стыд и позор. Что мешает просто поделить количество поездок на количество клиентов?

Кейс 7

Ну просто по рукам набить! Что, оконные функции нравятся так, что куча записей-дубликатов в выходном наборе даже не воспринимается как недостаток? Хоть бы DISTINCT добавили, что ли... Хотя на самом деле для решения задачи достаточно обычной агрегации.

К кейсам 3 и 4 особых претензий нет. Ну если не считать того, что и к ним применимы слова, сказанные для кейса 2. Кому нужен этот фарш?

Насколько материал оказался для вас полезен?

Как говорилось в одном анекдоте: "Не льстите себе, подойдите ближе".

Кейс 1 - Вы правы, в некоторых случаях WHERE EXISTS действительно более эффективен, особенно на больших объемах данных. Я привел запрос с WHERE IN для простоты примера, но могу добавить примечание, что для оптимизации на больших данных лучше использовать EXISTS. Пример будет полезен для многих читателей.

Кейс 2 - постарался показать, как собрать данные, но действительно, подготовка к анализу и оптимизация выборки — важные шаги. Обязательно добавлю это в материал, чтобы улучшить понимание задачи.

Кейс 5 - спасибо за совет, действительно, есть разные варианты работы с подзапросами.

Кейс 6 - пересмотрю формулы и упрощу вложения.

Кейс 7 - дублирование действительно нежелательно. Я использовал оконные функции для демонстрации, но DISTINCT или даже обычная агрегация, как вы верно подметили, были бы здесь логичнее.

Материал демонстрирует примеры SQL-запросов, отражающие базовый уровень владения SQL, необходимый для Junior Data Engineers. Основная цель — показать, как решать стандартные задачи на языке SQL, а не предоставить готовые данные для глубокой аналитики. Поэтому запросы сосредоточены на примерах фильтрации, агрегации и базовых аналитических функций. Конечно, возможна дальнейшая оптимизация.

Спасибо за ваши критику, такие замечания позволяют улучшить материал! Благодарю за обратную связь.

в некоторых случаях WHERE EXISTS действительно более эффективен, особенно на больших объемах данных

Данная логическая конструкция имеет три реализации - через INNER JOIN, через WHERE EXISTS и через WHERE IN.

Поскольку условием является подзапрос, а не короткий список литералов, то WHERE IN - самая медленная конструкция абсолютно всегда, без исключений. Слишком много накладных расходов.

INNER JOIN в данном случае неприменим, потому что не гарантируется уникальность выходной записи подзапроса по критерию сравнения/связывания. Формирование выходного набора потребует применения DISTINCT, что опять же делает этот вариант медленным.

WHERE EXISTS - гарантированно абсолютный и бесспорный лидер. И именно он должен применяться.

И объёмы данных тут не при чём. Просто на малых объёмах время именно выполнения запроса настолько мало, что разница во времени выполнения ниже точности определения этого самого времени (не забываем о наличии константы - время работы оптимизатора плюс время передачи результата).

Кейс 5 - .. действительно, есть разные варианты работы с подзапросами.

Да аллах бы с ими, с разными вариантами. Просто использованная вами форма никак не гарантирует однократности выполнения подзапроса. Сервер, конечно, достаточно умён, но при некоторых условиях он запросто может начать выполнять подзапрос на каждую запись основной таблицы. И чем сложнее запрос, тем больше вероятность такой пакости. Особенно при интерференции имён в разных областях видимости.

Кейс 6 - пересмотрю формулы и упрощу вложения.

Тут двойная вложенность - НЕ НУЖНА! Вообще. Получаемое вами значение avg_num_trips есть просто тупое COUNT(drives.drive_id) / COUNT(DISTINCT drives.client_id). А если надо учитывать клиентов, не имеющих поездок - COUNT(drives.drive_id) / COUNT(clients.client_id)

Если хотите попрактиковаться в написании аналитических запросов - зайдите на sqltest.online

В запросе номер 4 вернётся просто месиво из данных. Чтобы это была последовательность поездок, надо явно указывать порядок сортировки в order by всего запроса. А тогда row_number() вообще не особо нужен: можно отсортировать по client_id, start_time. Ну и ограничения по числу строк везде отсутствует, как это потом смотреть?

Задача - пронумеровать поездки. Запрос это и делает. Вы далее можете добавить сортировку по времени, разумеется.

Про нумерацию даже не сказано.

Задача: Определить порядок поездок для каждого клиента, отсортировав их по времени.

А я в решении прочёл полагание на то, что row_number все сделает за нас. Встречал решения, которые используют подобные предположения, но это сайд эффект, который в параллельной обработке может не сработать.

KeyLookup вам за непокрытый индекс спасиббо не скажет...

И да, Вычисляемое выражение в Where также отключит индекс.

А зачем имя и фамилия выделены в разные поля?

Sign up to leave a comment.

Articles