Эту статью я решил написать на первый взгляд будничную тему: нюансы использования Distinct при объединении таблиц оператором Concatenate, а также при использовании операторов Join и Keep. Но тема не так проста, как кажется. Статья окажется полезной для новичков, так как помогает лучше понять работу основных операторов скрипта, да и для профи некоторые нюансы, также могут быть интересными.
Distinct: Основы
Итак, вот что там говорит о Distinct справочное руководство:
НА ЗАМЕТКУ!
distinct — это предикат, используемый в том случае, если должны быть загружены только первые дублирующиеся записи.
Как я это понимал в самом начале работы с QlikView? Понимал так, что Distinct влияет на ту таблицу, которая загружается в блоке LOAD и никак по-другому.
Т.е. я думал, если мы будем делать следующее объединение:
LEFT JOIN (Table1)
LOAD Distinct
*
Resident Table2;
то у нас количество записей в таблице Table1 должно остаться неизменным, это казалось мне довольно логичным. На практике же получилось, что Disticnt влияет не только на Table2, но и на Table1.
Пример:
После выполнения данного кода я интуитивно ожидаю, что будет 6 записей из первой таблицы с заполненным полем Manager:
На самом же деле остаётся всего 3 записи, так как Distinct убирает дубли не только в Table1, но и в Table2:
Это я осознал только через год работы с QlikView.
В примере выше чтобы получить то, что я хочу, напрашивается перенос Distinct во второй LOAD:
Соответственно Distinct во втором блоке LOAD сразу же убирает дубли и последующий Left Join уже работает с загрузкой всех дублей из Table1.
На практике же часто хочется уменьшить количество строк в коде, когда мы выполняем Join сразу же, минуя формирование таблицы Table2. В данном случае можно просто не обратить внимания на потенциальное влияние Distinct на Table1:
В результате выполнения данного кода мы получим также 3 записи, как и в первом примере.
И если в примере с Inline всё довольно очевидно, то при загрузке данных из других источников легко упустить этот момент.
Join и Keep: Некоторые тонкости использования
После этого я попробовал то же самое, заменив Join на Keep, ожидая, что результат будет таким же (т.е. уберутся дубликаты из двух таблиц):
Но в данном случае первая таблица оказалась неизменной, дубликаты удалились только при формировании Table2. Получается, что Qlik сначала загрузил таблицу Table2, а уже потом выполнил операцию Keep. Итого получилось Table1 6 записей, Table2 3 записи.
Так, с Join и Keep разобрались.
Concatenate и Distinct
Прошло довольно много времени, когда выяснился очередной нюанс нашим младшим специалистом Кристиной, но уже при использовании Concatenate.
Для начала рассмотрим автоматическое объединение таблиц (одинаковое количество и названия полей)
Вместо возможно ожидаемых кем-то двух таблиц (Table1 и Table2), где 6 записей в первой и 3 во второй, мы получим одну таблицу, Table1, но, сколько в ней будет записей? Мои изначальные ожидания, что 9, 6 из первой таблицы, и 3 поля, как результат второго LOAD, но на самом деле мы получаем всего 3 записи, как оказалось, Distinct во втором LOAD влияет не просто на вторую, загружаемую таблицу, а на всё итоговое объединение данных.
Таблица, которую мы в итоге получаем:
Аналогично будет и при использовании принудительного объединения, для примера возьмём таблицы с разной структурой:
Вместо ожидаемых 9 записей, 6 уже загруженных записей из первого LOAD, и 3 новых — из второго, мы получаем только 6 уникальных записей, 3 из данных первого LOAD и 3 из данных второго.
Чтобы получить предполагаемый результат (в данном случае 9 записей), нужно отдельно загрузить таблицу, оставив уникальные значения, а уже после этого осуществлять объединение.
Таким образом, получаем таблицу, где записи из Table1 остаются с дубликатами плюс три новых уникальных записи из Table2:
Concatenate / NoConcatenate
В примере выше таблицы Table1 и Table2 имеют разную структуру, если же структура одинакова, то перед загрузкой Table2 нужно указать NoСoncatenate, без этого оператора произойдёт автоматическое объединение таблиц и следующий оператор Concatenate выдаст сообщение об ошибке, что Table2 не существует:
НА ЗАМЕТКУ! Все примеры в данной статье отрабатывают одинаково и на QlikView 11 и на Qlik Sence 3.0.
Эти случаи не часто встречаются на практике, у меня пример с Concatenate встретился один раз, случай же с Join появлялся чаще, примерно раз в несколько месяцев. И всё же, знать эти нюансы нужно, и осознанно ставить или не ставить Distinct при загрузке данных, для этого я и решил написать эту статью.
Встречались ли у вас интересные ситуации при формировании модели данных? Пишите в комментариях
Спасибо за внимание!
Здравствуйте, Илья
Спасибо за статью.
Именно такие нюансы сильно замедляют движение вперед.
Два дня ходишь и думаешь почему-же не получается — все же правильно и логично сделано?!
PS мне думается что в первом примере в загрузке Table2 Distinct быть не должно, а в Left Join должен быть Distinct.
Спасибо. Денис.
Денис, добрый день!
Нюансы действительно важные, их нужно узнавать, как можно раньше.
P.S. спасибо за замечание, картинку с первого примера я заменил, теперь статья стала более понятной!