﻿# Синтаксис EQL-запроса

> [HTML Version](eql-syntax.html)

EQL365 — язык запросов для поиска данных в ELMA365. С его помощью можно находить элементы приложений по значениям полей, объединять несколько условий, использовать параметры, выполнять поиск по датам, пользователям и связанным объектам.

В статье описаны правила составления EQL-запросов, доступные операции и функции, а также примеры простых и вложенных запросов.

О том, где можно использовать EQL-запросы, читайте в статьях [«Поисковые запросы на языке EQL365»](eql365-search.md) и [«Способы поиска в приложении»](360009669952.md).

## Подобрать EQL-конструкцию под задачу

| | |
|------|------|
| **Что нужно сделать ** | **Какой раздел выбрать** |
| Составить простой EQL-запрос | [Базовый EQL-запрос](#basic-search) |
| Узнать, как записывать строки, числа, даты и другие значения | [Как записывать значения в EQL-запросе](#assign-value) |
| Добавить в форму поиска поля для ввода значений и сохранить запрос как фильтр | [Создание и использование параметров EQL-запроса](#create-eql-parameters) |
| Сравнить значения, найти совпадение, пустое поле или одно из нескольких значений | [Операции поиска](#operations) |
| Объединить несколько условий или исключить условие | [Логические операторы](#logical-operators) |
| Указать дату, время или период относительно текущей даты | [Функции: Datetime(), Time(), RelativeDatetime()](#functions) |
| Найти записи, связанные с текущим пользователем | [Текущий пользователь — CurrentUser()](#current-user) |
| Указать определённый или любой элемент произвольного приложения | [Элемент коллекции — Refitem()](#refitem) |
| Посчитать количество элементов или результатов подзапроса | [Количество элементов — Count()](#count) |
| Найти элементы другого приложения по заданным условиям | [Операторы выборки в подзапросах](#subquery) |
| Обратиться к свойствам родительского или корневого приложения | [Вложенные подзапросы](#nested-queries) |


## Базовый EQL-запрос

Минимальный EQL-запрос состоит из трёх частей:

`\[код\_переменной\] операция значение`

````
начало примера

````
Пример

`\[price\] > 10000`

Запрос найдёт элементы, у которых значение поля с кодом `price` больше 10 000.

````
конец примера

````
При составлении запроса соблюдайте следующие правила:

1. Для обращения к свойству приложения укажите его код в квадратных скобках: `\[property\_name\]`.

2. После кода свойства укажите операцию поиска: математический знак или ключевое слово EQL365.

3. Искомое значение записывайте по правилам, установленным для типа свойства.

4. Для указания или вычисления значения можно использовать функции, например `Datetime()` или `CurrentUser()`.

5. Чтобы вводить значения после составления запроса и использовать их несколько раз, создайте параметры. Поля для параметров автоматически появятся в окне поиска.

6. Для поиска по нескольким условиям используйте логические операторы. Порядок проверки условий можно задать с помощью скобок.

7. Для сложных выборок используйте подзапросы. В них можно обращаться к свойствам любого приложения в системе.

8. Разделяйте все составляющие запроса пробелами.

При написании запроса можно использовать автозаполнение строки. Чтобы открыть список доступных свойств, функций и операторов, нажмите **Ctrl + Пробел**.

````
начало примера

````
Примеры

1. `\[company\_name\] = 'АвтоПром' or \[company\_name\] like 'Авто'` 

Поиск элементов приложения **Компании**, в которых поле **Название** полностью совпадает со значением АвтоПром или содержит значение Авто.

2. `\[\_\_createdAt\] >= Datetime(2025, 1) and \[\_\_createdAt\] < Datetime(2025, 2) and  \[price\] > 4000`

Поиск записей приложения **Заказы**, у которых в поле **Дата создания** указан январь 2025 года, а значение поля **Стоимость** больше 4 000 рублей.

3. `\[contract\] in (select \[\_\_id\] from \[documents.contracts\] where \[total\] > 10000)`

Поиск записей приложения **Контрагенты**, у которых в поле **Договор** указан элемент приложения с суммой больше 10 000 рублей.

````
конец примера

## ````
Как записывать значения в EQL-запросе

Значения в EQL-запросе записываются по-разному в зависимости от типа свойства. Например, текст указывается в одинарных кавычках, а числа — без кавычек. Основные правила и примеры приведены в таблице. Для дат, пользователей и связанных объектов ниже даны дополнительные пояснения.

| | | |
|------|------|------|
| **Тип свойства** | **Как записать значение** | **Пример** |
| **Строка** | Строкой в одинарных кавычках | `\[authors\_name\] like 'Алекс'` — поле **Имя автора** содержит значение **Алекс**.<br>`\[product\] in ('вентилятор', 'холодильник')` — поле **Продукт** содержит одно из указанных значений.<br>`\[authors\_name\] is null` — имя автора не указано. |
| **Число, Деньги** | Числом без кавычек. Дробная часть отделяется точкой | `\[size\] < 5.5` — в поле **Размер** указано значение меньше 5,5 метра.<br>`\[price\] >= 5000` — значение поля **Стоимость** больше или равно 5 000 рублей. |
| **Выбор «да/нет»** | Значением `true` без кавычек | `\[prepayment\] = true` — в поле **Предоплата** выбрано значение **Да**.<br>`\[prepayment\] <> true` — значение **Да** не выбрано. В поле указано **Нет**.<br>`\[prepayment\] is null` — поле не заполнено. |
| **Дата/время** | Строкой в одинарных кавычках. Части даты разделяются дефисами. Можно использовать сокращённую запись, добавлять время и часовой пояс.<br>Для сложных условий и относительных дат используйте функции: `Datetime()` и `Time()`, `RelativeDatetime()`. | `\[close\_date\] > '2025-01-31-12'` — поиск элементов с датой закрытия позже 31 января 2025 года 12:00.<br>`\[close\_date\] < '2025-01-31T12:30:00'` — дата закрытия раньше указанной, время без учёта часового пояса.<br>`\[close\_date\] > '2025-01-31T12:30+09:00'` — дата закрытия позднее указанной, время с часовым поясом UTC+09:00. |
| **Категория** | Кодом категории в одинарных кавычках | `\[payment\] in ('half', 'full')` — в поле **Оплата** выбрано одно из указанных значений. |
| **Номер телефона ** | Строкой в одинарных кавычках | `\[phone\] = '+71234567890'` |
| **Электронная почта** | Строкой в одинарных кавычках | `\[email\] = 'admin@example.com'` |
| **Ф. И. О.** | Строкой в одинарных кавычках | `\[contact\] like 'Иван'` — поле **Контактное лицо** содержит значение **Иван**.  |
| **Пользователи** | Идентификатором пользователя в одинарных кавычках, без пробелов | `\[responsible\] = '95806fe5-f8e8-460c-b2be-ce607068726c'` |
| **Приложение** | Идентификатором элемента в одинарных кавычках, без пробелов | `\[app\] = '018a1c61-c2b9-7701-86ab-d8b39a143465'` |
| **Произвольное приложение** | Строкой в одинарных кавычках. Путь состоит из кода раздела, кода приложения и при необходимости идентификатора элемента. Части пути разделяются двоеточиями и записываются без пробелов | `\[client\] = 'clients:contracts:1415381a-1197-11ee-be56-0242ac120002'` — указан определённый элемент приложения.<br>`\[client\] = 'clients:contracts'` — указан любой элемент приложения. |
| **Статус** | Числовым идентификатором статуса без кавычек | `\[\_\_status\] = 1` — элементу присвоен первый по счёту статус.  |


Чтобы указать в запросе конкретного пользователя, откройте раздел **Компания > Сотрудники**, выберите карточку пользователя и скопируйте идентификатор из адреса страницы.

Чтобы указать конкретный элемент приложения, откройте нужную запись и скопируйте идентификатор из адреса страницы.

Чтобы найти элементы, у которых свойство не заполнено, используйте операции `IS NULL` или `IS EMPTY`. Исключение составляют свойства типов **Номер телефона** и **Электронная почта**.

## Создание и использование параметров EQL-запроса

В EQL-запросе можно создать параметр для определённого свойства. В него можно подставлять разные значения и находить подходящие элементы приложения, не изменяя сам запрос.

Параметр отображается на форме поиска как дополнительное поле, в котором пользователь указывает искомое значение.

Запрос с параметрами можно [сохранить как фильтр](filters-for-search.md) и использовать повторно. Сохранённый фильтр появится на боковой панели окна расширенного поиска.

Чтобы создать параметр:

1. В квадратных скобках укажите код свойства приложения, по которому будет выполняться поиск.

2. Добавьте знак `=`, символ `@` и произвольное название параметра на русском или латинице.

3. Чтобы искать элементы по нескольким параметрам, объедините условия операторами `AND` или `OR`. Подробнее читайте в разделе [«Логические операторы»](#logical-operators).

(eql-syntax-1.png)

При работе с запросом, содержащим параметры, пользователь может:

- указать значения в появившихся полях и запустить поиск;

- сохранить запрос как фильтр. Кнопка **Сохранить** активна внизу окна, если значения параметров не заданы.

````
начало примера

````
Пример

`\[\_\_createdBy\] = @Пользователь AND \[budget\] = @Сумма`

В запросе созданы два параметра для поиска сделок по автору и сумме. На форме поиска появятся поля **Пользователь** и **Сумма**.

````
конец примера

## ````
Операции поиска

Операция поиска задаёт условие сравнения свойства с указанным значением, другим свойством или результатом функции. В EQL365 используются математические знаки и ключевые слова.

### Операции со знаками

Во всех таких операциях слева указывается код свойства, а справа — значение, другое свойство или функция.

#### Равно — =

Проверяет точное совпадение.

````
начало примера

````
Примеры 

1. `\[client\] = 'Иванов'`

Поиск клиента с указанным именем.

2. `\[payment\] = \[budget\]`

Поиск элементов, в которых значения полей Оплата и Бюджет совпадают.

3. `\[responsible\] = CurrentUser()`

Поиск элементов, в которых текущий пользователь указан ответственным.

````
конец примера

````
Операцию `=` нельзя применять к свойствам с подтипом **Несколько**. Для них используется `IN`.

Не рекомендуется использовать `=` со свойствами типа **Дата/время**, поскольку запрос проверяет точное совпадение значения.

#### Не равно — <>

Исключает точное совпадение.

````
начало примера

````
Примеры

1. ````
\[product\] <> 'Оборудование'

````
Поиск заказов, в которых в поле Продукт не указано значение Оборудование.

2. ````
\[payment\] <> \[budget\]

````
Поиск заказов, в которых значения полей Оплата и Бюджет не совпадают.

3. ````
\[responsible\] <> CurrentUser()

````
Поиск элементов, в которых текущий пользователь не указан ответственным.

````
конец примера

#### ````
Больше — >

Проверяет, что значение свойства больше указанного значения.

````
начало примера

````
Примеры

1. ````
\[price\] > 10000

2. \[payment\] > \[budget\]

3. \[shipping\_date\] > Datetime(2025, 1, 31, 12)

конец примера

#### ````
Больше или равно — >=

Проверяет, что значение свойства больше сравниваемого значения или совпадает с ним.

````
начало примера

````
Примеры

1. ````
\[price\] >= 10000

2. \[payment\] >= \[budget\]

3. \[shipping\_date\] >= Datetime('Today')

конец примера

#### ````
Меньше — <

Проверяет, что значение свойства меньше сравниваемого значения.

````
начало примера

````
Примеры

1. ````
\[price\] < 10000

2. \[payment\] < \[budget\]

3. \[shipping\_date\] < Datetime('Today')

конец примера

#### ````
Меньше или равно — <=

Проверяет, что значение свойства меньше сравниваемого значения или совпадает с ним.

````
начало примера

````
Примеры

1. ````
\[price\] <= 10000

2. \[payment\] <= \[budget\]

3. \[shipping\_date\] <= Datetime('Today')

конец примера

### ````
Операции с ключевыми словами

#### Частичное совпадение строки — LIKE

Операция `LIKE` используется для поиска частичного совпадения текста без учёта регистра. Она находит строки, содержащие указанное значение в любой части.

````
начало примера

````
Пример

`\[responsible\] like 'Алекс'`

Запрос найдёт элементы, в которых поле **Ответственный** содержит указанное значение.

````
конец примера

#### ````
Полное совпадение строки и поиск по шаблону — LIKEF

Операция `LIKEF` используется для поиска точного совпадения текста. С помощью специальных символов также можно задать положение искомого значения в строке и сузить результаты поиска.

Операцию `LIKEF` можно использовать со свойствами следующих типов:

- [Строка](360009707032.md);

- [Категория](360009707032.md#category);

- [Учётная запись](360009707032.md#account);

- [Номер телефона](360009707032.md#phone-number);

- [Электронная почта](360009707032.md#email);

- [Ф. И. О.](360009707032.md#full-name);

- [Ссылка](360009707032.md#link).

При составлении запроса используйте следующие символы:

- `\_` обозначает любой один символ. Его можно поставить до или после искомого значения;

- `%`  указывает, что до или после искомого значения может находиться любое количество символов. 

Символы `\_` и `%` можно комбинировать и использовать в запросе несколько раз для построения сложных шаблонов.

Если искомое значение содержит управляющий символ `\_` или `%`, экранируйте его обратной косой чертой `\\`.

````
начало примера

````
Примеры

1. ````
\[client\] likef 'Иван'

````
Запрос ищет записи, где поле **Клиент** содержит точное значение Иван. Например, Иван Краснов, Иван Круглов и т. д.

2. ````
\[string\] likef '\_010203'

````
Запрос ищет строки, которые начинаются с любого одного символа, после которого следует значение `010203`.

3. ````
\[phone\] likef '7912%'

````
Запрос находит записи, в которых номер телефона начинается с `7912`, а после него может находиться любое количество символов.

4. ````
\[order\_name\] likef 'Продукты%10\_2024'

````
Запрос находит заказы, название которых начинается со значения `Продукты`, затем содержит любое количество символов и заканчивается значением `10`, одним любым символом и значением `2024`.

5. ````
\[email\] likef '\_petrov\\%@example%'

````
Запрос находит адреса электронной почты, которые начинаются с одного любого символа, содержат значение `petrov%@example` и заканчиваются любым доменом. Символ `%`, входящий в искомое значение, экранируется обратной косой чертой `\\`.

````
конец примера

````
Для запросов с операциями `LIKE` и `LIKEF` может применяться[ равнозначность букв Е и Ё при поиске](360009669952.md#equivalentyoe). Администратор системы может отключить эту возможность.

#### Поле не заполнено — IS NULL и IS EMPTY

Операции используются для поиска элементов, у которых поле не содержит значения. Регистр написания операции не учитывается.

````
начало примера

````
Пример

1. ````
\[budget\] is null

2. \[budget\] is empty

````
Равнозначные запросы для поиска заказов, где не указан бюджет.

````
конец примера

#### ````
Вхождение в множество — IN

Операция `IN` проверяет, содержит ли свойство одно из указанных значений. Регистр при сравнении не учитывается.

Перечислите искомые значения в круглых скобках через запятую, с пробелом или без. Вместо списка значений можно использовать подзапрос.

Если в условии используется функция `CurrentUser()`, её и код свойства можно указывать с любой стороны операции `IN`.

````
начало примера

````
Примеры

1. ````
\[order\_number\] in (6,7,8,9)

````
Поиск всех заказов, в номерах которых содержатся перечисленные числа.

2. ````
\[client\] in ('Алексей', 'Андрей', 'Иванов')

````
Поиск всех клиентов с перечисленными именами.

3. ````
\[\_\_createdBy\] in CurrentUser() ````
или ````
CurrentUser() in \[\_\_createdBy\]

````
Равнозначные запросы для поиска всех элементов, созданных текущим пользователем системы.

4. Пример с подзапросом:

````
\[orders\] in (  
  select \[\_\_id\]  
  from \[documents.contracts\]  
  where \[total\] > 10000  
)

````
Выборка всех заказов, в договорах которых в поле Сумма указано значение более 10 000 рублей.   
Подробнее о составлении таких выражений читайте в разделе [«Подзапросы»](#subquery).

````
конец примера

## ````
Логические операторы

Логические операторы позволяют проверить несколько условий в одном запросе.

### Все условия — AND

Оператор `AND` объединяет несколько условий. В результаты поиска попадут элементы, для которых выполняются все условия.

````
начало примера

````
Примеры

1. ````
\[prepayment\] = 1000 and \[budget\] > 3000

````
Поиск заказов, в которых предоплата равна 1 000, а бюджет больше 3 000.

2. ````
\[\_\_createdAt\] >= Datetime(2025, 1) and \[\_\_createdAt\] < Datetime(2025, 3)

````
Поиск элементов, созданных в январе и феврале 2025 года.

````
конец примера

### ````
Хотя бы одно условие — OR

Оператор `OR` объединяет несколько условий. В результаты поиска попадут элементы, для которых выполняется хотя бы одно из них.

````
начало примера

````
**Примеры**

1. ````
\[order\_number\] in (6,7) or \[client\] is null

````
Поиск заказов, у которых номер равен `6` или `7` либо не заполнено поле **Клиент**.

2. Пример с подзапросом и оператором выборки ````
FROM\_SELECT\_WHERE````
:

````
\[client\] like 'Алекс'  
 or \[orders\] in (  
 from \[documents.contracts\]  
 select \[\_\_id\]  
 where \[total\] > 10000  
)

````
Поиск заказов, в которых имя клиента содержит значение `Алекс` или сумма связанного договора превышает 10 000 рублей.

````
конец примера

### ````
Условие не должно выполняться — NOT

Оператор `NOT` применяется к одному условию. В результаты поиска попадут элементы, для которых это условие не выполняется.

````
начало примера

````
**Примеры**

1. ````
not \[payment\] is null

````
Поиск счетов, в которых заполнено поле **Оплата**.

2. ````
not \[client\_name\] in ('Петров', 'Иванов')

````
Поиск заказов, в которых имя клиента не совпадает ни с одним из указанных значений.

````
конец примера

### ````
Порядок проверки условий

Если в запросе используется несколько логических операций, с помощью круглых скобок можно указать, какое условие должно выполняться первым. Скобки задают порядок вычисления условий в сложном выражении.

````
начало примера

````
Примеры

1. ````
not (\[client\_name\] like 'Алексей' or \[client\_name\] like 'Андрей')

````
Поиск заказов, в которых имя клиента не содержит ни значение `Алексей`, ни значение `Андрей`.

2. ````
(not \[client\_name\] = 'Алексей') and \[client\_name\] like 'Ал'

````
Поиск заказов, в которых имя клиента не равно `Алексей`, но содержит значение `Ал`.

````
конец примера

## ````
Функции

Функции позволяют задать или вычислить значение, которое используется в условии EQL-запроса.

### Дата — Datetime()

Функция `Datetime()` задаёт дату и при необходимости время. Параметры указываются в круглых скобках через запятую в следующем порядке:

1. год;

2. месяц;

3. день;

4. час;

5. минута;

6. секунда;

7. часовой пояс.

Обязателен только год. Остальные параметры можно не указывать или пропускать и переходить к другому по порядку. Если время не задано, используются значения `0` для часов, минут и секунд.

Вместо конкретной даты в функцию можно передать:

- `Today` — текущую дату;

- `Now` — текущее время.

**Важно:** запись даты функцией `Datetime(2025, 1, 31, 12)` равносильна строковой записи `'2025-01-31-12'`. Для простых фиксированных дат вы можете использовать любой из этих способов. 

````
начало примера

````
**Примеры**

1. ````
\[\_\_createdAt\] > Datetime(2024)

````
Поиск элементов с датой создания позднее 2024 года.

2. ````
\[\_\_createdAt\] > Datetime(2025, 1, 31)

````
Поиск элементов с датой создания позднее 31 января 2025 года.

3. ````
\[finish\_date\] > Datetime(2025, 2, '+09:00')

````
Поиск заказов, сборку которых завершили позднее февраля 2025 года, с учётом указанного часового пояса.

4. ````
\[\_\_createdAt\] < Datetime('Now')

````
Поиск элементов с датой создания ранее текущего времени.

5. ````
\[closing\_date\] > Datetime('Today')

````
Поиск сделок с датой закрытия позднее текущей даты.

6. ````
\[close\_date\] > Datetime(2025, 1, 31, 12)

````
Поиск элементов, у которых значение поля **Дата закрытия** позднее 31 января 2025 года, 12:00.

````
конец примера

### ````
Время — Time()

Функция `Time()` задаёт время. В круглых скобках через запятую указываются час, минута и секунда. Обязателен только час.

````
начало примера

````
Примеры

1. ````
\[closing\_time\] < Time(17)

````
Поиск сделок, закрытых ранее 17:00.

2. ````
\[closing\_time\] > Time(12, 30, 00)

````
Поиск сделок, закрытых позднее 12:30.

````
конец примера

### ````
Период относительно текущей даты — RelativeDatetime()

Функция `RelativeDatetime()` задаёт временной промежуток относительно текущей даты с учётом часового пояса, установленного в системе. Функцию можно использовать в условиях с операторами `=` и `IN`.

**Синтаксис функции:**

`RelativeDatetime('start', 'end')`

В функции всегда указываются два параметра:

- `start` — начало периода;

- `end` — окончание периода.

Параметры заключаются в одинарные кавычки и разделяются запятой. Для каждого параметра используется цифробуквенное выражение или комбинация таких выражений.

Числовая часть задаёт направление и количество периодов:

- отрицательное значение — прошедший период;

- положительное значение — будущий период;

- `0` — текущий период, знак `+` перед нулём не требуется.

Доступные буквенные обозначения разряда временного промежутка

- Час — `h` или `ч`;

- День — `d` или `д`;

- Неделя — `w` или `н`;

- Месяц — `m` или `м`;

- Квартал — `q` или `к`;

- Год — `y` или `г`;

Параметры вычисляются последовательно. Расчёт выполняется по календарным периодам, а не по фиксированному количеству единиц времени.

Например, если текущая дата — 11 декабря 2025 года, то значение `-1m` обозначает не предыдущие 30 дней, а прошлый календарный месяц. Началом периода будет 1 ноября 2025 года.

#### Как вычисляется начало периода

Параметр `start` задаёт начало периода. Вычисленное значение включается в результаты поиска.

Примеры:

- `0h` — с начала текущего часа;

- `+1m` — с начала следующего месяца;

- `-1w+1d` — от начала прошлой календарной недели прибавляется один день. Например, если сегодня понедельник, поиск начнётся со вторника прошлой недели.

#### Как вычисляется окончание периода

Параметр `end` задаёт окончание периода. При вычислении к наименьшей указанной единице времени добавляется единица. Полученное значение не включается в результаты: учитываются значения, которые меньше него.

Примеры:

- `0h` — до конца текущего часа;

- `0d` — до конца текущего дня;

- `+1m` — до конца следующего месяца;

- `-1w+1d` — расчёт начинается с понедельника прошлой календарной недели. Затем добавляются один день из параметра и ещё один день для определения верхней границы. Получается среда прошлой недели, которая не включается в период. Поэтому поиск выполняется до конца вторника прошлой недели.

Начало периода должно быть меньше его окончания. Если начало больше окончания или совпадает с ним, пользователь увидит ошибку о неверном формате относительных дат.

````
начало примера

````
Примеры 

1. `\[date\] IN RelativeDatetime('0d', '0d')`

Поиск за текущую дату.

2. `\[date\] IN RelativeDatetime('-1d', '-1d')`

Поиск за предыдущий день.

3. `\[date\] IN RelativeDatetime('0w', '0w')`

Поиск за текущую неделю.

4. `\[date\] IN RelativeDatetime('-1w', '-1w')`

Поиск за прошлую неделю.

5. `\[date\] IN RelativeDatetime('-7d', '-1d')`

Поиск за предыдущие семь дней.

6. `\[date\] IN RelativeDatetime('+1w', '+1w')`

Поиск за следующую неделю.

7. `\[date\] IN RelativeDatetime('-1w+2d', '-1w+3d')`

Поиск с прошлой среды до конца прошлого четверга.

8. `\[date\] IN RelativeDatetime('-1m', '+1m')`

Поиск с начала прошлого месяца до конца следующего месяца.

9. `\[\_\_createdAt\] IN RelativeDatetime('-1m','0d')`

Поиск всех элементов, созданных с начала прошлого месяца до текущей даты.

10. `\[date\] IN RelativeDatetime('0y+3q','0y')`

Поиск элементов начиная с третьего квартала текущего года до конца года. 

11. `\[date\] IN RelativeDatetime('0y-2m', '0y-1m')`

Поиск за последний и предпоследний месяцы прошлого года.

12. `\[date\] IN RelativeDatetime('+1y', '+1y0m')`

Поиск за первый месяц следующего года.

````
конец примера

### ````
Количество элементов — Count()

Функция `Count()` подсчитывает количество элементов:

- в свойстве с множественным значением;

- в результатах подзапроса.

В условии сравнения функция указывается перед свойством или подзапросом без пробела.

````
начало примера

````
Примеры 

1. `Count(\[orders\]) > 3`

Поиск компаний, для которых создано более трёх заказов.

2. Примеры с подзапросом:

````
Count(  
 from \[documents.contracts\]  
 where parent.\[\_\_id\] in \[client\]  
 and \[total\] > 10000  
) > 2

````
Поиск компаний, для которых создано более двух договоров с суммой в каждом свыше 10 000 рублей.

````
Count(  
 from \[\_clients.\_contracts\]  
 where parent.\[\_email\] = \[\_email\]  
 and parent.\[\_phone\] = \[\_phone\]  
) > 1

````
Поиск элементов приложения **Контакты**, в которых указаны одинаковые адреса электронной почты и номера телефонов.

Во втором и третьем примерах используется вложенный подзапрос с оператором `PARENT`.

````
конец примера

### ````
Текущий пользователь — CurrentUser()

Функция `CurrentUser()` возвращает идентификатор пользователя, который выполняет запрос. Полученное значение можно использовать в условии поиска по свойству приложения.

````
начало примера

````
**Пример**

`\[responsible\] = CurrentUser()`

Поиск заказов, за которые отвечает текущий пользователь.

````
конец примера

### ````
Элемент коллекции — Refitem()

Функция `Refitem()` используется для получения определённого или любого элемента из поля типа [Произвольное приложение](360009707032.md#arbitrary-app).

Состав функции зависит от задачи.

Чтобы найти записи, у которых в поле содержится ссылка на определённый элемент приложения, укажите:

- код раздела;

- код приложения;

- идентификатор элемента.

Чтобы найти записи, у которых в поле выбрано любое значение из заданного приложения, используйте один из способов:

- укажите только код раздела и код приложения;

- укажите код раздела, код приложения и неопределённый идентификатор элемента.

Параметры заключаются в одинарные кавычки и разделяются запятыми.

````
начало примера

````
**Примеры**

1. Поиск записи, связанной с определённым элементом приложения:

````
\[bill\] = Refitem(  
    'documents',  
    'bills',  
    '018a8dbb-04cd-7798-a363-aae245148b10'  
)

````
Поиск договоров, у которых в поле **Счёт** указан элемент с заданным идентификатором из приложения **Счета**.

2. Поиск записей, у которых в поле выбран любой элемент заданного приложения, можно указать только код раздела и код приложения:

`\[contract\] = Refitem('cleints', 'contracts')`

Или дополнительно указать неопределённый идентификатор:

````
\[contract\] = Refitem(  
    'clients',  
    'contracts',  
    '00000000-0000-0000-0000-000000000000'  
)

````
Оба запроса используются для поиска элементов, у которых в поле **Договор** выбрана любая запись из приложения **Договоры** раздела **Клиенты**.

3. Поиск незаполненного поля.

Чтобы найти элементы, у которых поле типа **Произвольное приложение** не заполнено, используйте операцию `IS NULL`:

`\[bill\] is null`

Поиск договоров, в которых не заполнено поле **Счёт**.

````
конец примера

## ````
Подзапросы

Подзапрос — это EQL-запрос, вложенный в другой запрос. В составе основного запроса он заключается в круглые скобки.

### Операторы выборки в подзапросах

Подзапросы позволяют находить элементы приложений по указанным значениям. Например, с помощью подзапроса можно найти карточки компаний, для которых договор оформлен не позднее определённой даты.

Параметры поиска в подзапросе задаются с помощью следующих операторов:

- `SELECT\_FROM\_WHERE` или `FROM\_SELECT\_WHERE` — используются для обращения к элементам из других разделов системы, а также к свойствам типа **Произвольное приложение**;

- `FROM\_WHERE` — используется для выборки элементов по свойствам текущего или другого приложения. Применяется вместе с:

	- операторами `PARENT` или `ROOT`, которые позволяют установить связь между приложениями и выполнить поиск элементов по указанному свойству;а

	- функцией `Count()`, которая определяет количество элементов, соответствующих условиям поиска.

#### Синтаксис операторов выборки

В каждом подзапросе указываются:

1. **Источник данных** — код приложения, из которого выбираются данные.

2. **Свойство для поиска** — свойство источника данных, которое используется при поиске.

3. **Условие поиска** — критерий, по которому фильтруются данные.

````
начало примера

````
**Примеры**

1. `\[clients\] in (select \[\_\_id\] from \[clients.orders\] where \[total\] > 1000) `

Выборка элементов приложения **Клиенты**, для которых созданы заказы с суммой более 1 000 рублей.

2. `\[contracts\] in (select \[\_\_id\] from \[clients.leads\] where \[\_\_name\] = 'ООО Пристань') `

Поиск договоров из свойства типа **Произвольное приложение**, где имя компании совпадает с указанным в запросе.

3. Примеры с вложенным подзапрос с оператором `PARENT`:

````
count(  
 from \[orders.products\]  
 where parent.\[product\_number\] = \[product\_number\]  
) > 1 

````
Выборка элементов приложения **Товары** с одинаковым значением в поле **Артикул**.

````
count(  
 from \[bookstore.book\]   
 where parent.\[\_\_id\] in \[authors\]  
) > 0 

````
Поиск авторов, в карточке которых указана хотя бы одна книга.

````
конец примера

### ````
Вложенные подзапросы

Подзапросы могут включать другие подзапросы. Для обращения к свойствам приложений с учётом уровня вложенности используются операторы:

- `PARENT` — обращается к свойствам родительского приложения, которое находится в запросе на один уровень выше;

- `ROOT` — обращается к свойствам корневого приложения, указанного в начале запроса. Например, это может быть приложение, со страницы которого выполняется EQL-поиск.

Примеры вложенных запросов

1. Предположим, раздел содержит два приложения: **Заказы** и **Контакты**. Заказ привязывается только к одному клиенту. Нужно проверить, что нет заказов, которые ошибочно указаны у более чем одного клиента. Для этого задайте EQL‑запрос со следующими условиями:

1. заказ указан в элементе приложения **Контакты** (`contacts`) в поле с кодом `order`;

2. количество найденных клиентов для заказа больше одного.

````


count(  
 from \[clients.contacts\]  
 where parent.\[\_\_id\] in \[order\]  
) > 1

````


где используется:

- функция `Count()`, чтобы посчитать найденные элементы из приложения **Контакты**;

- операторы `FROM\_WHERE` и `PARENT`, чтобы задать условие поиска заказов в приложении **Контакты**:

	- `FROM\_WHERE` указывает на приложение, в котором ищется свойство `\[\_\_id\]` приложения **Заказы**;

	- `PARENT` позволяет связать приложение **Заказы**, свойство которого используется для поиска;

- операция `>`, чтобы задать условие, при котором количество найденных клиентов для заказа больше одного.

2. Предположим, раздел содержит приложения: **Авторы книг**, **Книги** и **Договоры на копирайт**. Между авторами книг и договорами на копирайт нет прямой связи. Но оба эти приложения связаны с приложением **Книги**. В приложении **Авторы книг** нужно найти писателей, с которыми заключено более одного договора о правах на книгу. Для этого задайте EQL‑запрос и предусмотрите условия:

1. автор указан в элементе приложения **Книги** (`book`) в поле с кодом `authors`;

2. книга добавлена в элемент приложения **Договоры на копирайт** (`copyright`) в поле с кодом `book`;

3. книг, удовлетворяющих этим условиям, больше одной.

````


count(  
  from \[bookstore.book\]  
  where root.\[\_\_id\] in \[authors\]  
  and (count(  
   from \[bookstore.copyright\]   
   where parent.\[\_\_id\] = \[book\]  
   ) > 0)  
) > 1 

````


где используется:

- функция `Count()`, чтобы посчитать:

	- количество книг, для которых оформлены договоры на права;

	- количество авторов, у которых больше одной книги с оформленным договором на права;

- операторы `FROM\_WHERE` и `ROOT`, чтобы задать условие поиска авторов в приложении **Книги**:

	- `FROM\_WHERE` указывает на приложение, в котором ищется свойство `\[\_\_id\]` приложения **Авторы**;

	- `ROOT` позволяет связать приложение **Авторы**, свойство которого используется для поиска; 

- операторы `FROM\_WHERE` и `PARENT`, чтобы задать условие поиска книг в приложении **Договоры на копирайт**:

	- `FROM\_WHERE` указывает на приложение, в котором ищется свойство `\[\_\_id\]` приложения **Книги**;

	- `PARENT` позволяет связать приложение **Книги**, свойство которого используется для поиска;

- операция `>`, чтобы задать:

	- количество книг, для которых есть договоры на права (**>0**);

	- количество авторов, у которых больше одной книги с оформленным договором на права (**>1**).