Упражнение. Назначение переменных с помощью инструкции let

Завершено

Мы использовали метеорологический набор данных для агрегирования и визуализации данных. Здесь вы узнаете, как использовать инструкции let для представления переменных и организации сложных запросов.

Выражения let полезны для разбиения сложного выражения на несколько частей, определения констант за пределами текста запроса для удобочитаемости или определения переменной один раз и ее многократного использования в запросе. Инструкции можно использовать let для создания хорошо упорядоченных сложных запросов. Можно использовать несколько let операторов. За каждым оператором должна следовать точка с запятой (;).

Инструкции можно использовать let в различных ситуациях. На самом простом уровне они позволяют определить скалярные значения, на которые позже можно ссылаться в запросе, например, целочисленные, строковые, представляющие дату и время или любые другие значения. Вы можете создать отфильтрованное табличное представление, которое будет использоваться в качестве входных данных для запроса. Вы также можете создать функцию с помощью инструкции let.

Определение скалярного выражения с помощью оператора let

Вспомним, что предыдущие запросы отфильтрованы по расположению или минимальному повреждению. Давайте определим пограничные значения с помощью инструкции let в начале запроса.

Следующий запрос использует две инструкции let для определения скалярных значений, которые позже будут использоваться в качестве входных параметров в запросе. Первое определенное значение является числом, а второе — строкой. Все операторы let заканчивается точкой с запятой.

Обратите внимание на закомментированные части запроса, которые начинаются с двойной косой черты (//). Двойные косые черты указывают начало комментария, который продолжается до конца строки. Комментарии игнорируются при выполнении запросов.

  1. Выполните приведенный ниже запрос:

    Выполнить запрос

    let MinDamage = 1; // int
    let EventLocation = "ARIZONA"; // string
    StormEvents
    | where State == EventLocation
    | where DamageCrops + DamageProperty >= MinDamage
    | summarize Damage=round(avg(DamageProperty + DamageCrops)) by EventType
    | sort by Damage
    

    Вы должны получить результаты, аналогичные приведенным на следующем рисунке:

    Снимок экрана: запрос с оператором let и результатами его выполнения.

  2. Попробуйте изменить имя состояния или значение минимального повреждения и повторно запустить запрос. Как изменяются результаты?

Преобразование табличного результата в скалярное значение, используя toscalar в инструкции let

Далее посмотрим на числа наиболее часто встречаемых типов событий как функцию времени. Во-первых, необходимо выяснить, какой тип события является наиболее частым. Затем вы будете использовать это значение в запросе. Используйте таблицу StormEvents, чтобы найти максимальное значение EventType, подсчитав количество событий в каждом типе. Воспользуемся оператором project, чтобы вернуть только столбец EventType.

Перед началом создания выражения let выполните запрос, чтобы узнать, что представляет из себя событие на самом деле. Это позволяет убедиться, что запрос создает ожидаемые результаты.

Выполнить запрос

StormEvents
| summarize count() by EventType
| top 1 by count_
| project EventType

Вы должны получить результаты, аналогичные приведенным на следующем рисунке:

Снимок экрана: предварительный просмотр запроса let со сложным скаляром и результаты.

Обратите внимание, что запрос создал табличный результат с одним столбцом и одной строкой. Однако вам понадобится преобразовать его в скалярное значение, которое будет использоваться в качестве значения фильтра в основном запросе. Сначала определите имя переменной, которое требуется ввести, как MostFrequentEventType. Затем необходимо преобразовать табличный результат в скалярное значение, поместив весь запрос в функцию toscalar().

Предыдущие шаги обобщены в следующей инструкции let.

let MostFrequentEventType = toscalar(
    StormEvents
    | summarize count() by EventType
    | top 1 by count_
    | project EventType);

Обратите внимание, что эта инструкция сама по себе не является допустимым запросом, так как допустимый запрос должен содержать по крайней мере одну инструкцию, которая не является инструкцией let. Однако можно использовать это хранимое скалярное значение в запросе. Напомним, что необходимо просмотреть количество наиболее часто встречающихся событий в виде функции времени. Вы отфильтруете значение MostFrequentEventType, а затем суммируете количество по определенному интервалу времени.

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

Наконец, отрисуйте результаты по столбцам, чтобы получить гистограмму числа наиболее часто встречаемых типов событий, отбираемых по месяцам.

  1. Выполните приведенный ниже запрос:

    Выполнить запрос

    let MostFrequentEventType = toscalar(
        StormEvents
        | summarize count() by EventType
        | top 1 by count_
        | project EventType);
    StormEvents
    | where EventType == MostFrequentEventType
    | summarize count() by startofmonth(StartTime)
    | render columnchart
    

    Вы должны получить результаты, аналогичные приведенным на следующем рисунке:

    Снимок экрана: запрос let со сложным скаляром и результаты.

  2. Попробуйте изменить запрос, чтобы отобразить гистограмму наименее частого типа события по месяцам и повторного запустите его.

Создание инструкции let с табличными выходными данными

В предыдущих примерах сохранялось скалярное значение, которое потом использовалось в качестве входного параметра в запросе. Однако можно также использовать инструкцию let для создания табличных данных, которые затем используются в качестве входных данных для запроса.

  1. Отфильтруйте таблицу StormEvents по событиям, которые косвенно или непосредственно вызвали смерть. Затем верните подмножество столбцов с помощью оператора project. Это выражение предоставляет табличные выходные данные с именем KillerStorms. Используйте инструкцию let в качестве начальных входных данных для запроса.

    let KillerStorms =
        StormEvents
        | where DeathsDirect + DeathsIndirect > 0
        | project State, EventType, Deaths=DeathsDirect + DeathsIndirect;
    
  2. Затем можно воспользоваться некоторыми функциями агрегирования, о которых вы узнали в предыдущих уроках. Выполните приведенный ниже запрос:

    Выполнить запрос

    let KillerStorms =
        StormEvents
        | where DeathsDirect + DeathsIndirect > 0
        | project State, EventType, Deaths=DeathsDirect + DeathsIndirect;
    KillerStorms
    | summarize DistinctKillerEventTypes=dcount(EventType), TotalDeaths=sum(Deaths) by State
    | sort by TotalDeaths
    

    Вы должны получить результаты, аналогичные приведенным на следующем рисунке:

    Снимок экрана: табличный оператор let и результаты.

  3. Проверьте результаты. Суммируются ли все события в столбце DistinctKillerEventTypes так называемые "штормы убийцы?"

Создание определяемой пользователем функции с помощью инструкции let

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

В инструкции let вы объявите имя функции, аргументы и текст, используя следующий общий синтаксис.

let function=(argument1:datatype, argument2:datatype) {functionbody};

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

Имя аргумента Тип данных Description
portion real Часть общего числа событий, для которой требуется вычислить процентное значение.
итог real Общее число событий.

С помощью функции round() ответ округляется до двух десятичных разрядов.

Собрав выражения воедино, пользовательская функция, описанная в выражении let, выглядит следующим образом.

let Pcent = (portion:real, total:real){round(100 * portion / total, 2)};
  1. Используйте эту инструкцию let в следующем запросе.

    Выполнить запрос

    let Pcent = (portion: real, total: real) { round(100 * portion / total, 2) };
    StormEvents
    | extend Damage = DamageCrops + DamageProperty
    | summarize TotalEvents = count(), TotalDamagingEvents = countif(Damage > 0) by EventType
    | project EventType, TotalDamagingEvents, TotalEvents, Percentage = Pcent(TotalDamagingEvents, TotalEvents)
    | sort by EventType asc
    

    Вы должны получить результаты, аналогичные приведенным на следующем рисунке:

    Снимок экрана: оператор let и результаты.

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

Посмотрите на результаты. Что означают проценты? Обратите внимание на то, что запрос вызывает функцию Pcent, определенную в инструкции let. Входными данными, используемыми в этой функции, являются столбцы TotalDamagingEvents и TotalEvents. Это означает, что ищется процент событий, вызвавших ущерб, из общего числа событий.