Использование функций между записями: Peek, Previous и Exists
Эти функции используются, если для оценки текущей записи требуется значение из ранее загруженных записей данных.
В этой части учебного пособия мы изучим функции Peek(), Previous() и Exists().
Peek()
Функция Peek() возвращает значение поля в таблице для строки, которая уже загружена. Можно указать номер строки или таблицу. Если номер строки не указан, будет использована последняя запись, загруженная ранее.
Синтаксис:
Элемент Row должен быть целым числом. 0 обозначает первую запись, 1 обозначает вторую и т. д. Отрицательные числа указывают порядок с конца таблицы. -1 обозначает последнюю прочитанную запись.
Если элемент row не указан, принимается значение -1.
Tablename является меткой таблицы без двоеточия на конце. Если элемент tablename не указан, принимается текущая таблица. При использовании вне оператора LOAD или в ссылке на другую таблицу должен включаться элемент tablename.
Previous()
Функция Previous() находит значение выражения expr с помощью данных из ранее введенной записи, которая не была сброшена из-за предложения where. В первой записи внутренней таблицы функция возвратит значение NULL.
Синтаксис:
Функцию Previous() можно использовать вложенным образом, чтобы получить доступ к более ранним записям. Данные выбираются из входного источника напрямую, что также позволяет ссылаться на поля, которые не были загружены в программу Qlik Sense, то есть даже если они не были сохранены в связанной базе данных.
Exists()
Функция Exists() определяет, загружено ли определенное значение поля в поле в скрипте загрузки данных. Функция возвращает значение TRUE или FALSE, таким образом, ее можно использовать в предложении where оператора LOAD или IF.
Синтаксис:
Поле должно существовать в данных, загруженных скриптом к текущему времени. Expression — выражение, которое вычисляет значение поля для поиска в указанном поле. При его отсутствии принимается значение текущей записи в указанном поле.
Использование функций Peek() и Previous()
В своем простом виде функции Peek() и Previous() используются для указания определенных значений в таблице. В таблице Employees представлена выборка данных, которые будут загружены в этом упражнении.
Дата | Hired | Terminated |
---|---|---|
1/1/2011 | 6 | 0 |
2/1/2011 | 4 | 2 |
3/1/2011 | 6 | 1 |
4/1/2011 | 5 | 2 |
На данный момент происходит сбор данных только для месяцев, найма и увольнения, поэтому мы собираемся добавить поля для элементов Employee Count и Employee Var с помощью функций Peek() и Previous(), чтобы увидеть месячную разницу по сотрудникам в целом.
Выполните следующие действия.
- Откройте приложение Учебное пособие по написанию скриптов продвинутого уровня.
- Добавьте новый раздел скрипта в Редакторе загрузки данных.
- Вызовите раздел Employees.
-
Под элементом DataFiles в меню справа щелкните Выбрать данные.
- Загрузите, а затем выберите Employees.xlsx.
- В окне Выбрать данные из щелкните команду Вставить скрипт.
-
Измените скрипт, чтобы он выглядел так:
[Employees Init]: LOAD rowno() as Row, Date(Date) as Date, Hired, Terminated, If(rowno()=1, Hired-Terminated, peek([Employee Count], -1)+(Hired-Terminated)) as [Employee Count] FROM [lib://DataFiles/Employees.xlsx] (ooxml, embedded labels, table is Sheet1);
- Добавьте следующее выражение в конец скрипта:
- Щелкните команду Загрузить данные.
Скрипт должен выглядеть следующим образом:
Даты в поле данных Date на листе Excel имеют формат ММ/ДД/ГГГГ. Чтобы обеспечить правильное распознавание дат с помощью формата, указанного в системных переменных, к полю Date необходимо применить функцию Date.
Функция Peek() позволяет находить любое значение, загруженное для указанного поля. В первую очередь следует проверить, равняется ли значение rowno() единице (1). Если оно равняется 1, то элемента Employee Count не будет, поэтому поле заполняется значением разницы между Hired и Terminated.
Если значение rowno() больше 1, мы посмотрим на элемент Employee Count за последний месяц и используем это число, чтобы добавить его к значению разницы элемента Hired за этот месяц минус количество сотрудников из элемента Terminated.
Также обратите внимание, что в функции Peek() мы используем (-1). Поэтому программа Qlik Sense должна обратиться к записи над текущей записью. Если значение (-1) не указано, программа Qlik Sense будет считать, что вы хотите увидеть предыдущую запись.
[Employee Count]:
LOAD
Row,
Date,
Hired,
Terminated,
[Employee Count],
If(rowno()=1,0,[Employee Count]-Previous([Employee Count])) as [Employee Var]
Resident [Employees Init] Order By Row asc;
Drop Table [Employees Init];
Функция Previous() позволяет находить последнее значение, загруженное для указанного поля. В первую очередь следует проверить, равняется ли значение rowno() единице (1). Если оно равняется 1, то элемента Employee Var не будет, поскольку для элемента Employee Count предыдущего месяца нет записей. Поэтому мы просто вводим 0 для данного значения.
Если элемент rowno() больше 1, то будет элемент Employee Var, поэтому мы посмотрим на элемент Employee Count последнего месяца и вычтем это число из элемента Employee Count для текущего месяца, чтобы создать значение в поле Employee Var.
Скрипт должен выглядеть следующим образом:
[Employees Init]:
LOAD
rowno() as Row,
Date(Date) as Date,
Hired,
Terminated,
If(rowno()=1, Hired-Terminated, peek([Employee Count], -1)+(Hired-Terminated)) as [Employee Count]
FROM [lib://DataFiles/Employees.xlsx]
(ooxml, embedded labels, table is Sheet1);
[Employee Count]:
LOAD
Row,
Date,
Hired,
Terminated,
[Employee Count],
If(rowno()=1,0,[Employee Count]-Previous([Employee Count])) as [Employee Var]
Resident [Employees Init] Order By Row asc;
Drop Table [Employees Init];
На новом листе обзора приложения создайте таблицу, используя поля Date, Hired, Terminated, Employee Count и Employee Var в качестве столбцов таблицы. Полученная таблица должна выглядеть следующим образом:
Функции Peek() и Previous() позволяют намечать определенные строки в таблице. Самая большая разница между этими двумя функциями заключается в том, что функция Peek() позволяет пользователю увидеть поле, которое еще не загружено в скрипт, тогда как функция Previous() позволяет увидеть только уже загруженное поле. Функция Previous() работает с входными данными оператора LOAD, а функция Peek() работает с выходными данными оператора LOAD. (Такая же разница, как между элементами RecNo() и RowNo().) Это значит, что эти две функции будут вести себя по-разному, если есть предложение Where.
Поэтому функцию Previous() лучше использовать в ситуации, когда необходимо показать разницу текущего значения с предыдущим. В примере мы вычисляли, как изменялись данные по сотрудникам из месяца в месяц.
Функцию Peek() лучше использовать, когда целью является поле, которое еще не загружено в таблицу, или когда требуется наметить определенную строку. Это было показано в примере, где мы вычисляли элемент Employee Count, посмотрев данные элемента Employee Count предыдущего месяца, а затем добавили разницу между нанятыми и уволенными сотрудниками для текущего месяца. Помните, что в оригинальном файле не было поля Employee Count
Использование Exists()
Функция Exists() часто используется с предложением Where в скрипте, чтобы загружать данные, если соответствующие данные уже загружены в модель данных.
В следующем примере мы также используем функцию Dual(), чтобы назначить числовые значения строкам.
Выполните следующие действия.
- Создайте новое приложение и дайте ему имя.
- Добавьте новый раздел скрипта в Редакторе загрузки данных.
- Вызовите раздел People.
- Введите следующий скрипт:
- Щелкните команду Загрузить данные.
- Создайте новый лист и присвойте ему имя.
- Откройте новый лист и щелкните Изменить лист.
- Добавьте стандартную таблицу на лист с измерением AgeBucket и назначьте визуализации имя Возрастные группы.
- Добавьте линейчатую диаграмму на лист с измерением AgeBucket и мерой Count([AgeBucket]). Назовите визуализацию Number of people in each age group.
- Измените свойства таблицы и линейчатой диаграммы согласно своим предпочтениям, а затем щелкните Готово.
Полученный лист будет выглядеть примерно так:
//Add dummy people data
PeopleTemp:
LOAD * INLINE [
PersonID, Person
1, Jane
2, Joe
3, Shawn
4, Sue
5, Frank
6, Mike
7, Gloria
8, Mary
9, Steven,
10, Bill
];
//Add dummy age data
AgeTemp:
LOAD * INLINE [
PersonID, Age
1, 23
2, 45
3, 43
4, 30
5, 40
6, 32
7, 45
8, 54
9,
10, 61
11, 21
12, 39
];
//LOAD new table with people
People:
NoConcatenate LOAD
PersonID,
Person
Resident PeopleTemp;
Drop Table PeopleTemp;
//Add age and age bucket fields to the People table
Left Join (People)
LOAD
PersonID,
Age,
If(IsNull(Age) or Age='', Dual('No age', 5),
If(Age<25, Dual('Under 25', 1),
If(Age>=25 and Age <35, Dual('25-34', 2),
If(Age>=35 and Age<50, Dual('35-49' , 3),
If(Age>=50, Dual('50 or over', 4)
))))) as AgeBucket
Resident AgeTemp
Where Exists(PersonID);
DROP Table AgeTemp;
В скрипте поля Age и AgeBucket загружаются, только если поле PersonID уже загружено в модель данных.
Обратите внимание на таблицу AgeTemp. В ней для поля PersonID указаны значения возраста 11 и 12, но поскольку эти идентификаторы не были загружены в модель данных (в таблице People), они исключены предложением Where Exists(PersonID). Это предложение также можно записать следующим образом: Where Exists(PersonID, PersonID).
Результат работы скрипта имеет следующий вид:
Если бы ни одно значение поля PersonID в таблице AgeTemp не было загружено в модель данных, то поля Age и AgeBucket не были бы объединены в таблицу People. Использование функции Exists() может помочь предотвратить потерю записей/данных в модели данных, т. е. поля Age и AgeBucket, с которыми никто из людей не связан.
Функция Dual() очень полезна в скрипте или в выражении диаграммы, когда необходимо назначить строке числовое значение.
В скрипте выше есть приложение, которое загружает значения возраста. Было принято решение поместить эти значения в блоки, поэтому можете создавать визуализации на основе противопоставления блоков со значениями возраста фактическим значениям возраста. Есть блок для людей младше 25 лет, от 25 до 35 лет и так далее. С помощью функции Dual() блокам со значениями возраста можно назначить числовое значение, которое позднее можно использовать для сортировки блоков со значениями возраста в списке или диаграмме. Поэтому, как на листе приложения, в результате сортировки в конце списка появляется сообщение «Нет возраста».