Перейти к основному содержимому

Использование функций между записями: Peek, Previous и Exists

НА ЭТОЙ СТРАНИЦЕ

Использование функций между записями: Peek, Previous и Exists

Эти функции используются, если для оценки текущей записи требуется значение из ранее загруженных записей данных.

В этой части учебного пособия мы изучим функции Peek(), Previous() и Exists().

Peek()

Функция Peek() находит значение поля в таблице для строки, которая уже загружена или существует во встроенной памяти. Можно указать номер строки или таблицу.

Syntax:  

Peek(fieldname [ , row [ , tablename ] ] )

Элемент Row должен быть целым числом. 0 обозначает первую запись, 1 обозначает вторую и т. д. Отрицательные числа указывают порядок с конца таблицы. -1 обозначает последнюю прочитанную запись.

Если элемент row не указан, принимается значение -1.

Tablename является меткой таблицы без двоеточия на конце. Если элемент tablename не указан, принимается текущая таблица. При использовании вне оператора LOAD или в ссылке на другую таблицу должен включаться элемент tablename.

Previous()

Функция Previous() находит значение выражения expr с помощью данных из ранее введенной записи, которая не была сброшена из-за предложения where. В первой записи внутренней таблицы функция возвратит значение NULL.

Syntax:  

Previous(expression)

Функцию Previous() можно использовать вложенным образом, чтобы получить доступ к более ранним записям. Данные выбираются из входного источника напрямую, что также позволяет ссылаться на поля, которые не были загружены в программу Qlik Sense, то есть даже если они не были сохранены в связанной базе данных.

Exists()

Функция Exists() определяет, загружено ли определенное значение поля в поле в скрипте загрузки данных. Функция возвращает значение TRUE или FALSE, таким образом, ее можно использовать в предложении where оператора LOAD или IF.

Syntax:  

Exists(field [, expression ] )

Поле должно существовать в данных, загруженных скриптом к текущему времени. Expression — выражение, которое вычисляет значение поля для поиска в указанном поле. При его отсутствии принимается значение текущей записи в указанном поле.

Использование функций Peek() и Previous()

В своем простом виде функции Peek() и Previous() используются для указания определенных значений в таблице. В таблице Employees представлена выборка данных, которые будут загружены в этом упражнении.

Выборка данных из таблицы 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(), чтобы увидеть месячную разницу по сотрудникам в целом.

Выполните следующие действия.

  1. Откройте приложение Учебное пособие по написанию скриптов продвинутого уровня.
  2. Добавьте новый раздел скрипта в Редакторе загрузки данных.
  3. Вызовите раздел Employees.
  4. Под элементом DataFiles в меню справа щелкните Выбрать данные.

  5. Загрузите, а затем выберите Employees.xlsx.
  6. Примечание: Убедитесь, что в разделе Field names выбран параметр Embedded field names, чтобы включить имена полей таблицы при загрузке данных.
  7. В окне Выбрать данные из щелкните команду Вставить скрипт.
  8. Скрипт должен выглядеть следующим образом:

    LOAD "Date", Hired, Terminated FROM [lib://DataFiles/Employees.xlsx] (ooxml, embedded labels, table is Sheet2);

  1. Измените скрипт, чтобы он выглядел так:

    [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 Sheet2);

  2. Даты в поле данных 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 будет считать, что вы хотите увидеть предыдущую запись.

  1. Добавьте следующее выражение в конец скрипта:
  2. [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 Sheet2);
    
    [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];

  1. Щелкните команду Загрузить данные.
  2. На новом листе обзора приложения создайте таблицу, используя поля Date, Hired, Terminated, Employee Count и Employee Var в качестве столбцов таблицы. Полученная таблица должна выглядеть следующим образом:

    В следующей таблице в скрипте используются функции Peek и Previous
    Table following use of Peek and Previous in script.

Функции Peek() и Previous() позволяют намечать определенные строки в таблице. Самая большая разница между этими двумя функциями заключается в том, что функция Peek() позволяет пользователю увидеть поле, которое еще не загружено в скрипт, тогда как функция Previous() позволяет увидеть только уже загруженное поле. Функция Previous() работает с входными данными оператора LOAD, а функция Peek() работает с выходными данными оператора LOAD. (Такая же разница, как между элементами RecNo() и RowNo().) Это значит, что эти две функции будут вести себя по-разному, если есть предложение Where.

Поэтому функцию Previous() лучше использовать в ситуации, когда необходимо показать разницу текущего значения с предыдущим. В примере мы вычисляли, как изменялись данные по сотрудникам из месяца в месяц.

Функцию Peek() лучше использовать, когда целью является поле, которое еще не загружено в таблицу, или когда требуется наметить определенную строку. Это было показано в примере, где мы вычисляли элемент Employee Count, посмотрев данные элемента Employee Count предыдущего месяца, а затем добавили разницу между нанятыми и уволенными сотрудниками для текущего месяца. Помните, что в оригинальном файле не было поля Employee Count

Примечание: Чтобы узнать дополнительные сведения об использовании функций Peek() и Previous(), см. эту запись блога в Qlik Community: Peek() vs Previous() – When to Use Each. Поведение обсуждается в контексте QlikView. Однако логика в равной степени относится к Qlik Sense.

Использование Exists()

Функция Exists() часто используется с предложением Where в скрипте, чтобы загружать данные, если соответствующие данные уже загружены в модель данных.

В следующем примере мы также используем функцию Dual(), чтобы назначить числовые значения строкам.

Выполните следующие действия.

  1. Создайте новое приложение и дайте ему имя.
  2. Добавьте новый раздел скрипта в Редакторе загрузки данных.
  3. Вызовите раздел People.
  4. Введите следующий скрипт:
  5. //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;

  1. Щелкните команду Загрузить данные.
  2. В скрипте поля Age и AgeBucket загружаются, только если поле PersonID уже загружено в модель данных.

    Обратите внимание на таблицу AgeTemp. В ней для поля PersonID указаны значения возраста 11 и 12, но поскольку эти идентификаторы не были загружены в модель данных (в таблице People), они исключены предложением Where Exists(PersonID). Это предложение также можно записать следующим образом: Where Exists(PersonID, PersonID).

    Результат работы скрипта имеет следующий вид:

    В следующей таблице в скрипте используется функция Exists
    Table following use of Exists in script.

    Если бы ни одно значение поля PersonID в таблице AgeTemp не было загружено в модель данных, то поля Age и AgeBucket не были бы объединены в таблицу People. Использование функции Exists() может помочь предотвратить потерю записей/данных в модели данных, т. е. поля Age и AgeBucket, с которыми никто из людей не связан.

  3. Создайте новый лист и присвойте ему имя.
  4. Откройте новый лист и щелкните команду Изменить.
  5. Добавьте стандартную таблицу на лист с измерением AgeBucket и назначьте визуализации имя Возрастные группы.
  6. Добавьте линейчатую диаграмму на лист с измерением AgeBucket и мерой Count([AgeBucket]). Назовите визуализацию Number of people in each age group.
  7. Измените свойства таблицы и линейчатой диаграммы согласно своим предпочтениям, а затем щелкните Готово.

    Полученный лист будет выглядеть примерно так:

    Лист с группировками по возрасту
    Sheet with groupings by age.

Функция Dual() очень полезна в скрипте или в выражении диаграммы, когда необходимо назначить строке числовое значение.

В скрипте выше есть приложение, которое загружает значения возраста. Вы решили поместить эти значения в блоки, поэтому можете создавать визуализации на основе противопоставления блоков со значениями возраста фактическим значениям возраста. Есть блок для людей младше 25 лет, от 25 до 35 лет и так далее. С помощью функции Dual() блокам со значениями возраста можно назначить числовое значение, которое позднее можно использовать для сортировки блоков со значениями возраста в списке или диаграмме. Поэтому, как на листе приложения, в результате сортировки в конце списка появляется сообщение «Нет возраста».

Примечание: Чтобы узнать дополнительные сведения о функциях Exists() и Dual(), см. эту запись блога в Qlik Community: Dual & Exists – Useful Functions (Dual и Exists — полезные функции)