Примеры запросов

Данная статья доступно объясняет некоторые реальные примеры запросов.

Пример 1: Просмотр/редактирование учетных записей пользователей

Просмотр или изменение различных настроек учетных записей является общей административной задачей. Язык запроса может помочь администраторам AggreGate Server выполнить массовые изменения нескольких учетных записей пользователей или посмотреть определенные настройки множества учетных записей в одной упорядоченной таблице.

Выбор информации одного пользователя

Для доступа к основным настройкам учетной записи пользователя мы используем переменную "userInfo" ("Информация о пользователе"), заданную в контексте Пользователь. Значение данной переменной имеет одну запись с различными полями, в которых записаны имя/фамилия пользователя, страна и т.д.

Ниже представлен типичный вид переменной информации о пользователе:

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

Текст запроса:

SELECT
*
FROM
users.admin:childInfo

Результатом данного запроса будет являться таблица, отображающая значение переменной childInfo, заданной в контексте users.admin.

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

Данный запрос состоит из двух разделов: SELECT и FROM. Раздел SELECT предлагает нам выбрать все поля ("*"). Раздел FROM содержит одну контекстную ссылку ("users.admin:childInfo"), которая используется для построения таблицы, в которой будет выполняться запрос. Содержание и формат данной таблицы в точности совпадут с переменной childInfo.

Все поля в результате запроса будут доступны для редактирования, кроме тех полей, которые определены как доступные только для чтения в формате переменной childInfo.

При просмотре или изменении свойств какого-либо контекста (такого как контекст "Пользователь") вы увидите описания переменных, а не их имена. Однако в тесте запроса нам нужно использовать имена переменных: они обычно показываются во всплывающих окнах при наведении мыши на описание переменных.

Результат запроса:

Выбор информации всех пользователей

Теперь мы будем выбирать свойства всех пользователей в системе:

Текст запроса:

SELECT 
*
FROM
users.*:childInfo

Контекстная ссылка (users.*:childInfo) в тексте данного запроса по сути является маской контекстов. Во время выполнения запроса данная маска преобразуется в список всех контекстов пользователей, доступных пользователю, выполняющему запрос. Для получения более подробной информации обратитесь к главе Контекстные ссылки.

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

Данный запрос встроен в дистрибутив AggreGate Server. Он называется Все пользователи.

Результат запроса:

Например, вы изменяете имя и фамилию некого пользователя и сохраняете изменения:

Изменения сразу же отображаются во всей системе:

Сортировка  списка пользователей

Теперь мы произведем сортировку таблицы.

Текст запроса:

SELECT 
*
FROM
users.*:childInfo order by childInfo$name desc

Данный запрос выдает таблицу, схожую с указанной выше, но строки в данной таблице упорядочиваются по значению поля name в формате переменной childInfo в нисходящем порядке. Запрос содержит состоящую из двух частей ссылку на поле (childInfo$name), используемую для ссылки на поле таблицы, построенной при разрешении контекстной ссылки users.*:childInfo.

При изучении значения переменной "childInfo"  и других переменных AggreGate Client в пользовательском интерфейсе AggreGate Server описания полей отображаются в заголовке таблицы, а не в именах полей. Однако мы должны использовать имя поля, чтобы ссылаться на него в тексте запроса. Имена полей обычно отображаются во всплывающих окнах, которые появляются при наведении мыши на заголовок поля:

   

Использование альтернативных имен таблиц

Мы можем редактировать запрос и задать альтернативное имя info для нашей контекстной ссылки, а затем использовать трехкомпонентную контекстную ссылку, которая будет включать данное альтернативное имя:

SELECT 
 *
FROM
 users.*:childInfo as info
ORDER BY
 info.childInfo$name desc

Результат запроса будет такой же, как и предыдущий.

Ограничение выборки полей

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

Текст запроса:

SELECT 
childInfo$name, childInfo$firstname, childInfo$lastname
FROM
users.*:childInfo
ORDER BY
childInfo$name desc

Данный запрос содержит несколько ссылок на поля в разделе ВЫБРАТЬ. Так как поля задаются в явной форме, результат запроса будет нередактируемым, если мы не добавим поля обратной записи. Добавлять их мы будем в следующих примерах.

Результат данного запроса будет содержать только три столбца.

Результат запроса:

Добавление выражений

В данном случае мы будем использовать выражение языка запроса для отображения имен и фамилий пользователей в одном столбце, чтобы упростить процесс обработки данных. Мы также добавим новый столбец в запрос - Country (страна пользователя).

Текст запроса:

SELECT 
 childInfo$name,
 CASEWHEN((childInfo$firstname IS NULL), '', childInfo$firstname)  || ' ' || CASEWHEN((childInfo$lastname IS NULL), '', childInfo$lastname),
 childInfo$country
FROM
 users.*:childInfo
ORDER BY
 childInfo$name desc

Данный запрос выбирает три поля в исходной таблице. Первое и третье содержат имя пользователя и страну соответственно. Значение второго поля рассчитывается при помощи выражения. Данное выражение получает имя пользователя, добавляет в конце место и заполняет его фамилией пользователя. Двойные вертикальные черты (||) являются стандартным оператором SQL, используемым для соединения строк. Имя и фамилия изменяются при помощи встроенной функции CASEWHEN, чтобы отображалась пустая строка в том случае, если значение имени или фамилии является NULL ("<Не установлено>"). Имейте в виду, что второй столбец формируется автоматически.

Результат запроса:

Использование альтернативных имен полей

Теперь мы зададим название для второго столбца, чтобы сделать результат более удобным для чтения.

Текст запроса:

SELECT 
childInfo$name,
CASEWHEN((childInfo$firstname IS NULL), '', childInfo$firstname) || ' ' || CASEWHEN((childInfo$lastname IS NULL), '', childInfo$lastname) as name,
childInfo$country
FROM
users.*:childInfo
ORDER BY
childInfo$name desc

Второй столбец в результате запроса отныне называется "name" (имя).

Результат запроса:

Возможность редактирования результата

Чтобы было возможно изменить страну пользователя, добавьте поле обратной записи, таким образом делая отчет редактируемым. Для этого нам нужно назначить альтернативное имя для контекстной ссылки ("table alias"),  потому как поля обратной записи (CONTEXT_ID, PARENT_ID и RECORD_INDEX) должны быть заданы для определенной контекстной ссылки. Чтобы определить, какая запись должна быть записана обратно, необходимо использовать альтернативное имя. Внимательно прочтите приведенный ниже пример, чтобы полностью в этом разобраться.

Текст запроса:

SELECT 
info.childInfo$name,
CASEWHEN((info.childInfo$firstname IS NULL), '', info.childInfo$firstname) || ' ' || CASEWHEN((info.childInfo$lastname IS NULL), '', info.childInfo$lastname) as name,
info.childInfo$country,
info.CONTEXT_ID,
info.PARENT_ID,
info.RECORD_INDEX
FROM
users.*:childInfo as info
ORDER BY
info.childInfo$name desc

В результате данного запроса столбец "country" будет редактируемым. Столбец "username" останется доступным для чтения, потому что он так определен в исходной переменной ("userInfo"). Столбец "name" доступен только для чтения, т.к. он рассчитывается при помощи выражения.

Результат запроса:

Фильтрация списка пользователей

Теперь добавим к запросу несколько правил фильтра. Для примера выберем только тех пользователей, чьи имена пользователей (usernames) не содержат слово "test".

Текст запроса:

SELECT 
info.childInfo$name,
CASEWHEN((info.childInfo$firstname IS NULL), '', info.childInfo$firstname) || ' ' || CASEWHEN((info.childInfo$lastname IS NULL), '', info.childInfo$lastname) as name,
info.childInfo$country,
info.CONTEXT_ID,
info.PARENT_ID,
info.RECORD_INDEX
FROM
users.*:childInfo as info
WHERE
info.childInfo$name NOT LIKE '%test%'
ORDER BY
info.childInfo$name desc

Данный запрос содержит дополнительный раздел ГДЕ, определяющий, какие записи должны попадать в результат.

Результат запроса:

Ограничение количества строк в результате запроса

Последняя строка следующего примера включает раздел ОГРАНИЧИТЬ, используемый для ограничения количества строк в результате запроса.

Текст запроса:

SELECT 
info.childInfo$name,
CASEWHEN((info.childInfo$firstname IS NULL), '', info.childInfo$firstname) || ' ' || CASEWHEN((info.childInfo$lastname IS NULL), '', info.childInfo$lastname) as name,
info.childInfo$country,
info.CONTEXT_ID,
info.PARENT_ID,
info.RECORD_INDEX
FROM
users.*:childInfo as info
WHERE
info.childInfo$name NOT LIKE '%test%'
ORDER BY
info.childInfo$name desc
LIMIT 1 OFFSET 1

Результат данного запроса содержит только две (LIMIT 2) записи (2-ую и 3-ю) из результата предыдущего запроса. Здесь мы используем OFFSET 1. Это означает, что мы получим 2 записи (LIMIT 2), начиная со второй записи (OFFSET 1). Оператор OFFSET дает команду AggreGate брать записи, начиная со второй (номер первой записи - 0).

Результат запроса:

Пример 2:  просмотр/изменение учетных записей device server

Данный пример похож на выборку основных свойств всех пользователей, описанную в предыдущем примере, однако, здесь мы используем переменную deviceServerInfo (Информация устройства), заданную в контексте"deviceServer".

Текст запроса:

SELECT
*
FROM
users.*.deviceservers.*:deviceServerInfo

Текст данного запроса включает одну контекстную ссылку (users.*.deviceservers.*:deviceServerInfo) с маской контекста, которая распространяется на все контексты deviceServer, доступные при наличии прав доступа у пользователя, выполняющего запрос. Результаты данного запроса редактируемы, за исключением полей, которые определены как доступные только для чтения в переменной deviceServerInfo.

Данный запрос встроен в дистрибутив AggreGate Server. Он называется Все Device Servers.

Пример 3:  просмотр статистики трафика device server

Данный пример показывает применение контекстных ссылок, включающих в себя множество переменных/полей.

Текст запроса:

SELECT 
info.deviceServerInfo$owner,
info.deviceServerInfo$name,
info.status$servertods,
info.status$dstoserver
FROM
users.*.deviceservers.*:status:deviceServerInfo as info
ORDER BY
info.deviceServerInfo$owner,
info.deviceServerInfo$name

Контекстная ссылка в данном запросе ("users.*.deviceservers.*:status:deviceServerInfo") ссылается на две переменные, определенные в контексте "deviceServer": на указанную выше "deviceServerInfo" и "status" ("Статус устройства"), которая содержит реальные значения относительно работы Device Server. Значения обеих переменных включают только одну запись, поэтому итоговая таблица, которая сформируется после преобразования этой  контекстной ссылки, будет содержать все поля, появляющиеся в в значениях обеих переменных, и одну запись на каждое Device Server доступное пользователю, выполняющему запрос.

Из этой таблицы мы выбираем четыре столбца: два, которые появляются в значении deviceServerInfo (Владелец и имя Device Server) и два из status (Входящий и исходящий трафик). Таблица упорядочивается по двум полям: сначала по владельцу Device Server, затем по имени Device Server (потому что некоторые Device Server могут принадлежать одному пользователю).

Данный запрос встроен в дистрибутив AggreGate Server. Он называется Статистика трафика Device Server.

Пример 4:  вызов серверов устройств

Данный пример показывает, как функции контекста могут быть использованы в данном запросе.

Текст запроса:

SELECT 
 *
FROM
 external_device_servers.*:buzz()

Данный запрос очень интересен, потому что у него нет выхода, однако, он дает побочный эффект на сервере. Он  содержит одну контекстную переменную ("external_device_servers.*:buzz()"), которая включает в себя функцию buzz() ("Вызвать Device Server"), заданную в контексте "deviceServer". Данная функция вызывается без параметров, что обозначено пустыми скобками. Функция "Вызвать устройство" заставляет Device Server мерцать диодами для его физической идентификации. Таким образом, данный запрос помогает определить местонахождение всех устройств в сегменте локальной сети. Важно запустить действие Обнаружить <Device Server до выполнения запроса. Данное действие позволяет AggreGate Server найти все локальные Device Server, отправляя широковещательные сетевые запросы. Для получения более подробной информации обратитесь к разделу Внешние серверы устройств.

Если обнаружение не было выполнено, у контекста Внешние серверы устройств не будет дочерних, маска контекста external_device_servers.* не преобразуется ни в какой контекст, и при выполнении запроса не будут совершаться действия.

Выход функции buzz() не содержит полей, поэтому данный запрос не возвращает никаких данных. Но его выполнение приводит к тому, что все внешние Device Server начинают "мигать", таким образом становится проще их обнаружить.

Данный запрос встроен в дистрибутив AggreGate Server. Он называется "Вызвать все внешние Device Servers".

Пример 5:  расчет общего трафика всех серверов устройств

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

Текст запроса:

SELECT 
 SUM(status$servertods) as server_to_ds,
 SUM(status$dstoserver) as ds_to_server
FROM
 users.*.deviceservers.*:status

В одном из предыдущих примеров мы упоминали переменную status ("Статус Device Server"), заданную в контексте "deviceServer", которая содержит статистику трафика между AggreGate Server и Device Server. Данный запрос раcсчитывает, сколько байт было отправлено на видимые в данный момент Device Server и сколько было принято от них. Результат запроса содержит одну запись, потому что используется функция агрегации SUM.

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

Данный пример можно изменить для использования других функций агрегации:

  • AVG поможет рассчитать средний трафик Device Server

  • MIN и MAX могут применяться для расчета минимального и максимального трафика соответственно

  • COUNT может использоваться для обнаружения нескольких Device Server (хотя это не самый лучший  способ)

Пример 6:

Выполнение запроса по нескольким таблицам

Данный пример иллюстрирует выполнение запросов по нескольким таблицам (построенным из нескольких контекстных ссылок).

Текст запроса:

SELECT 
 d.deviceServerInfo$owner || '.' || d.deviceServerInfo$name as device_server,
 d.deviceServerInfo$blocked,
 u.childInfo$city,
 u.childInfo$country
FROM
 users.*:childInfo as u, users.*.deviceservers.*:deviceServerInfo as d
WHERE
 u.childInfo$name = d.deviceServerInfo$owner

Данный запрос имеет две контекстные ссылки в разделе FROM. Первая используется для построения таблицы, содержащей все базовые настройки всех пользователей, вторая - для формирования таблицы базовых настроек всех Device Server. Эти таблицы затем объединяются, основываясь на формуле в разделе WHERE ("u.childInfo$name = d.deviceServerInfo$owner"). Результат запроса имеет четыре поля: первое содержит полное имя устройства в виде "Имя владельца"."Имя Device Server". Второе отображает статус Device Server "Блокировано". Два остальных столбца показывают город и страну пользователя, к которому относятся Device Server (которые, вероятно, могут оказаться городом и страной, где расположено Device Server).

Пример 7: Использование объединить

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

Когда AggreGate  используется для сетевого управления, AggreGate Server работает с устройствами по протоколу SNMP. Каждое устройство SNMP обладает так называемой таблицей интерфейса (переменная ifTable контекста устройства), в которой содержится статистика сетевых интерфейсов устройства. Приведенный ниже запрос находит все сетевые интерфейсы всех устройств SNMP, чей статус равен "down" (т.е. поле ifOperStatus равно 2).

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

SELECT 
 info.info$description, ift.ifTable$ifDescr, ift.ifTable$ifOperStatus
FROM
 users.*.devices.*:ifTable as ift LEFT OUTER JOIN users.*.devices.*:info as info ON ift$CONTEXT_ID = info$CONTEXT_ID
WHERE
 ift.ifTable$ifOperStatus = 2

Дополнительные примеры

Получение события входа пользователя в систему

Данный запрос вызывает функцию get() и фильтрует полученную таблицу по имени пользователя (username).

SELECT
*
FROM
events:get("users", "login") as logins
WHERE
logins.get$username = 'operator'

Имейте в виду, что те же результаты можно получить, добавив выражение фильтра в вызов функции get():

SELECT
*
FROM
events:get("users", "login", "{username} == 'operator'") as logins

Обнаружение сетевых устройств c минимальным временем отклика

Данный запрос обнаруживает все сетевые устройства, время отклика которых превышает 500 мсек и отображает их имена вместе с временем отклика.

SELECT 
 info.info$description AS device,
 ping.ping$averageTime AS average_round_trip_time
FROM
 users.*.devices.*:info AS info
RIGHT OUTER JOIN  
 users.*.devices.*:ping AS ping
ON
 ping$CONTEXT_ID = info$CONTEXT_ID
WHERE
 ping.ping$averageTime > 500
ORDER BY
 ping.ping$averageTime DESC

Обнаружение устройств высокой загрузки ЦП

Данный запрос обнаруживает все сетевые устройства SNMP, у которых средняя загрузка всех процессоров превышает 90%. Он превосходно работает с мультипроцессорными устройствами.

SELECT 
 info.info$description AS device,
 avg(processors.hrProcessorTable$hrProcessorLoad) AS processor_utilization_percentage
FROM
 users.*.devices.*:hrProcessorTable AS processors
LEFT OUTER JOIN
 users.*.devices.*:info as info
ON
 processors$CONTEXT_ID = info$CONTEXT_ID
GROUP BY
 device
HAVING
 avg(processors.hrProcessorTable$hrProcessorLoad) > 90
ORDER BY
 processor_utilization_percentage DESC

Группирование устройств SNMP по типу

Данный запрос рассчитывает количество устройств SNMP каждого типа (тип определяется переменной sysObjectID,  предоставляемой самим устройством) и выводит результат в таблицу. Имейте в виду, что описания каждого типа устройства берутся из общей таблицы, которая называется deviceTypes.

SELECT 
 coalesce(types.value$description, snmp.sysObjectID$sysObjectID) AS device_type,
 COUNT(*) AS device_count
FROM
 users.*.devices.*:status:sysObjectID AS snmp
LEFT JOIN
 common.deviceTypes:value AS types
ON
 snmp.sysObjectID$sysObjectID = types.value$type
WHERE
 snmp.status$driver = 'com.tibbo.linkserver.plugin.device.snmp'
GROUP BY
 device_type
ORDER BY
 device_count DESC

Получение статистики настроек устройства

Данный запрос использует функцию статистика, заданную в контексте Утилиты для извлечения последних значений канала статистики. Канал настроен для подсчета ошибок интерфейса сетевых устройств, которые возникают каждый час/день/месяц.

Запрос группирует таблицы интерфейсов всех устройств в одну и использует ее как основу (FROM users.*.devices.*:ifTable AS interfaces). Затем он слева присоединяяет данные последнего часа из двух каналов статистики -- "ifInOctets" и "ifOutOctets" (LEFT OUTER JOIN utilities:statistics("users.*.devices.*", "ifInErrors", null, "hour") AS in_errors). И, наконец, слева таблицы присоединяется информация об устройстве. Запрос также осуществляет фильтрацию, сортировку и ограничение количества рядов.

SELECT
info.info$description AS device,
interfaces.ifTable$ifDescr AS interface,
in_errors.statistics$average * 3600 AS incoming_errors,
out_errors.statistics$average * 3600 AS outgoing_errors
FROM
users.*.devices.*:ifTable AS interfaces
LEFT OUTER JOIN
utilities:statistics("users.*.devices.*", "ifInErrors", null, "hour") AS in_errors
ON
interfaces.ifTable$ifIndex = in_errors.statistics$key
AND
interfaces$CONTEXT_ID = in_errors.statistics$context
LEFT OUTER JOIN
utilities:statistics("users.*.devices.*", "ifOutErrors", null, "hour") AS out_errors
ON
interfaces.ifTable$ifIndex = out_errors.statistics$key
AND
interfaces$CONTEXT_ID = out_errors.statistics$context
LEFT OUTER JOIN
users.*.devices.*:info AS info
ON
info$CONTEXT_ID = interfaces$CONTEXT_ID
WHERE
 length(interfaces.ifTable$ifDescr) > 1
ORDER BY
 incoming_errors + outgoing_errors DESC
LIMIT
 10

Составление списка сотрудников по отделам

В AggreGate Time and Attendance система обрабатывает данные посещения для держателей карт, образуя сложную иерархию, которая включает организации, отделы и, возможно, подразделения. Поскольку путь контекста каждого сотрудника начинается с пути контекста подразделения, к которому он относится, мы можем создать запрос, который создал бы список сотрудников по подразделениям:

SELECT
divisions.childInfo$name,
cardholders.childInfo$name
FROM
organizations.Organization1.divisions.*.cardholders.*:childInfo as cardholders,
organizations.Organization1.divisions.*:childInfo as divisions
WHERE
substring(cardholders.CONTEXT_ID, 1, length(divisions.CONTEXT_ID)) = divisions.CONTEXT_ID

Получение тревог, активных для множества устройств

В приведенном ниже примере каждое устройство имеет табличное пользовательское свойство custom_childContext,  которое приводит список всех устройств, зависимых от него. Это свойство имеет поле contextPath, которое содержит пути зависимых устройств.

Запрос проверяет триггеры, представленные в таблицах activeInstances всех тревог. Выбираются только триггеры, чье поле источник равно контекстному пути выбранного устройства (i.CONTEXT_ID) или представлено в таблице custom_childContext выбранного устройства.

Таким образом, запрос возвращает триггеры тревог, активные как для данного устройства (dev1), так и для его зависимых устройств.

SELECT 
*
FROM
users.*.alerts.*:activeInstances AS at
WHERE
at.activeInstances$source IN
(
SELECT
 i.CONTEXT_ID
FROM users.admin.devices.dev1:info AS i
UNION SELECT
 c.custom_childContexts$contextPath
FROM users.admin.devices.dev1:custom_childContexts AS c
)

Объединение исторических значений множества переменных

Функция variableHistory может загружать исторические значения любой переменной контекста. Это подходит для отображения этих значений в отчете, на панели инструментов и т.д. Но что если вы хотите показать множество переменных в одной таблице? Например, вы измеряете температуру и историю и хотите, чтобы измерения были представлены в виде единой таблицы. Вот решение.

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

SELECT
  sineTimeString, sineTime,  sineValue, triangleTime, triangleValue
FROM
  (
  SELECT
    TO_CHAR(sine.variableHistory$vUpdateTime, 'DD.MM.YYYY H:MI:SS') as sineTimeString, sine.variableHistory$vUpdateTime as sineTime, sine.variableHistory$value as sineValue
  FROM
    utilities:variableHistory("users.admin.devices.demoVirtualDevice", "sine", 'dateAdd(now(), -10, "m")') as sine
  )
JOIN
  (
  SELECT
    TO_CHAR(triangle.variableHistory$vUpdateTime, 'DD.MM.YYYY H:MI:SS') as triangleTimeString, triangle.variableHistory$vUpdateTime as triangleTime, triangle.variableHistory$value as triangleValue
  FROM
    utilities:variableHistory("users.admin.devices.demoVirtualDevice", "triangle", 'dateAdd(now(), -10, "m")') as triangle
  )
ON
sineTimeString = triangleTimeString

Объединение результатов нескольких подзапросов

Приведенный ниже запрос ссылается на три других запроса, представляя список их переменных data в разделе FROM основных и вложенных утверждений SELECT. Результаты трех запросов соединяются вместе, используя операторы UNION.

SELECT
 hpux.data$icon AS icon,
 hpux.data$device AS device,
 hpux.data$context AS context,
 hpux.data$cpu AS cpu,
 hpux.data$max_threshold as max_threshold,
 hpux.data$min_threshold as min_threshold,
 hpux.data$max_threshold - hpux.data$cpu as margin,
 CASEWHEN(hpux.data$max_threshold - hpux.data$cpu < 0,
   2,
   CASEWHEN(hpux.data$max_threshold - hpux.data$cpu < 10, 1, 0) ) as condition
FROM
 users.admin.queries.cpu_HPUX:data as hpux
UNION ALL
(SELECT
 standard.data$icon AS icon,
 standard.data$device AS device,
 standard.data$context AS context,
 standard.data$cpu AS cpu,
 standard.data$max_threshold as max_threshold,
 standard.data$min_threshold as min_threshold,
 standard.data$max_threshold - standard.data$cpu as margin,
 CASEWHEN(standard.data$max_threshold - standard.data$cpu < 0,
   2,
   CASEWHEN(standard.data$max_threshold - standard.data$cpu < 10, 1, 0) ) as condition
FROM
 users.admin.queries.cpu_standard:data as standard
UNION ALL
(SELECT
 sun.data$icon AS icon,
 sun.data$device AS device,
 sun.data$context AS context,
 sun.data$cpu AS cpu,
 sun.data$max_threshold as max_threshold,
 sun.data$min_threshold as min_threshold,
 sun.data$max_threshold - sun.data$cpu as margin,
 CASEWHEN(sun.data$max_threshold - sun.data$cpu < 0,
   2,
   CASEWHEN(sun.data$max_threshold - sun.data$cpu < 10, 1, 0) ) as condition
FROM
 users.admin.queries.cpu_Sun:data as sun))
ORDER BY
 margin

Выполнение выражений из запроса

В этом примере показано, как оценивать выражения AggreGate из запросов. В запросе перечислены переменные настройки устройства (технически, переменные, принадлежащие удаленной группе и ее подгруппам) вместе с их значениями. Значения извлекаются вызовом функции EVALUATE_TO_STRING, которая выполняет вызов функции языка выражений getVariable() и кодирует полученные таблицы в строки с помощью функции encode(). Вызов getVariable() ссылается на контекст по умолчанию (на который указывает функция dc()), поэтому этот контекст по умолчанию передается функции EVALUATE_TO_STRING с помощью ссылки на поле variables$CONTEXT_ID.

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

SELECT 
variables.variables$name as name,
EVALUATE_TO_STRING('encode(getVariable(dc(), "'+variables.variables$name+'"))', variables$CONTEXT_ID, null) as value
FROM
users.admin.devices.device1:variables as variables
WHERE
SUBSTRING(variables.variables$group, 1, 7) = 'remote|'