> For the complete documentation index, see [llms.txt](https://navixy.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://navixy.com/docs/analytics/ru/dashboard-studio/writing-sql-queries.md).

# Написание SQL-запросов

Пишите PostgreSQL-запросы, оптимизированные для визуализаций Dashboard Studio. Изучите шаблоны доступа к данным, выбор слоя и лучшие практики производительности

Dashboard Studio использует SQL для извлечения данных из схем IoT Query. Вы пишете SQL в двух контекстах: в редакторах панелей, где операторы используются для визуализаций, и в отдельном SQL-редакторе для исследования данных. На этой странице объясняется, как писать эффективный SQL для обоих контекстов, с упором на требования к визуализациям, поскольку у них есть особые структурные ограничения.

### Где используется SQL

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

[**Запросы визуализаций**](#how-to-write-sql-for-visualizations) питают отдельные панели в отчетах. Вы пишете эти операторы на вкладке **SQL Query** редактора панели. Каждая панель выполняет один оператор, который должен возвращать данные в определенной структуре, соответствующей типу визуализации. Эти операторы выполняются при загрузке или обновлении отчетов, поэтому производительность важна для пользовательского опыта. SQL для визуализаций не может изменять данные; все операторы выполняются как операции SELECT только для чтения над схемами IoT Query.

**Отчеты** используют тот же подход к SQL для визуализаций, что и панели мониторинга. Отчет выполняет один запрос, который одновременно питает три представления: таблицу данных, диаграмму и карту местоположения. Запрос должен возвращать все столбцы, необходимые для всех трех компонентов, поэтому включите столбцы координат, времени и метрик вместе в один SELECT.

[**SQL-редактор**](#how-to-use-the-sql-editor) поддерживает исследование и экспорт данных. Откройте SQL Editor на левой боковой панели в разделе Tools. Напишите любой оператор SELECT, чтобы изучить структуру данных, проверить предположения или экспортировать результаты в CSV. SQL Editor показывает полные таблицы результатов с сортировкой по столбцам и предоставляет метрики выполнения. Используйте его для проверки логики перед добавлением SQL в панели визуализации или для разового извлечения данных, которому не нужна визуализация.

{% hint style="info" %}
**Ключевое отличие**: SQL для визуализаций должен соответствовать точным структурам столбцов, тогда как операторы в SQL Editor могут возвращать любой формат результата. Сначала проверьте сложную логику в SQL Editor, а затем адаптируйте ее для визуализаций.
{% endhint %}

### Как писать SQL для визуализаций

<figure><img src="https://1999959041-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2Fgit-blob-e0648cf843ae5d39993031c1d6f2cb81f594ba03%2Fimage%20(8).png?alt=media" alt=""><figcaption></figcaption></figure>

SQL для визуализаций должен возвращать определенное количество столбцов и типы данных. Dashboard Studio не может отрисовать столбчатую диаграмму из трех столбцов или статическую плитку из текстовых данных. Перед написанием оператора проверьте раздел Dataset Requirements на вкладке SQL Query, чтобы точно узнать, что ожидает выбранная визуализация. В таблице ниже приведены поддерживаемые типы визуализаций:

| Визуализация                        | Требование к запросу         | Пример                                                            |
| ----------------------------------- | ---------------------------- | ----------------------------------------------------------------- |
| [Статическая плитка](#stat-tiles)   | Одно числовое значение       | `SELECT COUNT(*) FROM schema.table`                               |
| [Столбчатая диаграмма](#bar-charts) | Два столбца: category, value | `SELECT column1, COUNT(*) FROM schema.table Группа BY column1`    |
| [Круговая диаграмма](#pie-charts)   | Два столбца: метка, значение | `SELECT category, SUM(value) FROM schema.table GROUP BY category` |
| [Таблица](#tables)                  | Любые столбцы                | `SELECT column1, column2, column3 FROM schema.table`              |
| [Текст](#text-panels)               | Запрос не требуется          | Markdown, HTML или обычный текст                                  |
| [Карты](#maps)                      | Столбцы широты и долготы     | `SELECT latitude, longitude FROM schema.table`                    |

<details>

<summary>Плитки со статистикой</summary>

Плитки статистики отображают одиночные числовые значения. Операторы должны возвращать ровно одну строку с одним числовым столбцом:

{% code title="Всего поездок в текущем месяце" overflow="wrap" %}

```sql
SELECT COUNT(*) as value
ИЗ processed_common_data.trips
WHERE поездка_start_time >= DATE_TRUNC('month', CURRENT_DATE);
```

{% endcode %}

{% code title="Общее пройденное расстояние (км)" overflow="wrap" %}

```sql
SELECT ROUND(SUM(trip_distance_meters) / 1000.0, 1) as value
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '7 days';
```

{% endcode %}

Имя столбца не имеет значения, важно лишь, чтобы результатом было одно числовое значение. Dashboard Studio отображает это значение с форматированием, которое вы настраиваете в параметрах визуализации.

</details>

<details>

<summary>Столбчатые диаграммы</summary>

Диаграммы с столбцами требуют ровно двух столбцов: category (текст или дата) и value (числовой). Первый столбец становится осью X, второй — высотой столбцов:

{% code title="Поездки на объект" overflow="wrap" %}

```sql
С device_owner AS (
  SELECT DISTINCT ON (o.device_id) o.device_id, o.object_label
  FROM raw_business_data.objects o
  WHERE o.is_deleted IS NOT TRUE
  ORDER BY o.device_id, o.object_id
)
SELECT 
  d.object_label как категория,
  COUNT(*) as value
FROM processed_common_data.trips t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.trip_start_time >= DATE_TRUNC('month', CURRENT_DATE)
GROUP BY d.object_label
ORDER BY value DESC;
```

{% endcode %}

Группа по текстовому столбцу. `raw_business_data.vehicles.vehicle_type` содержит целочисленный код, а не имя, поэтому при группировке по нему столбцы получают подписи `1`, `2`, `3`.

Этот `device_Владелец` блок вверху не является необязательным, когда вы присоединяете метки Объекта к Поездкам или событиям. См. [Как объединить метки Объект](#how-to-join-object-labels).

{% code title="Ежедневное количество поездок" overflow="wrap" %}

```sql
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as category,
  COUNT(*) as value
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY DATE_TRUNC('day', trip_start_time)
ORDER BY category;
```

{% endcode %}

Используйте `ORDER BY` для управления порядком столбцов. Сортируйте по значению для ранжированных сравнений или по категории для прогрессий временных рядов.

</details>

<details>

<summary>Круговые диаграммы</summary>

Круговые диаграммы требуют ровно двух столбцов: label (текст) и value (числовое значение). Первый столбец становится метками секторов, второй определяет размеры секторов:

{% code title="Поездки по начальной зоне" %}

```sql
SELECT 
  start_zone как label,
  COUNT(*) as value
ИЗ processed_common_data.trips
WHERE trip_start_time >= DATE_TRUNC('month', CURRENT_DATE)
  AND start_zone IS NOT NULL
ГРУППИРОВАТЬ ПО start_zone
ORDER BY value DESC
LIMIT 10;
```

{% endcode %}

Добавьте предложения LIMIT для категорий с большим количеством значений. Круговые диаграммы с 20+ срезами становятся нечитаемыми; ограничьте их 10-15 лучшими категориями.

</details>

<details>

<summary>Таблицы</summary>

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

{% code title="Детали последней поездки" %}

```sql
SELECT 
  device_id,
  trip_start_time,
  время окончания поездки,
  ROUND(Поездка / 1000.0, 1) as distance_km,
  ОКРУГЛЬМАТЬ(поездка_длительность_в_секундах / 60.0) как duration_minutes,
  max_speed
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY trip_start_time DESC
LIMIT 100;
```

{% endcode %}

Имена столбцов становятся заголовками таблицы. Используйте псевдонимы с пробелами для читаемых заголовков: `ROUND(trip_distance_meters / 1000.0, 1) as "Расстояние (km)"`.

</details>

<details>

<summary>Текстовые панели</summary>

Текстовые панели отображают содержимое Markdown, HTML или обычный текст. Они не выполняют SQL-запрос.

На **Содержимое** вкладке, выберите параметр в разделе **Режим содержимого**:

* **Markdown** (по умолчанию) поддерживает форматирование, такое как заголовки и ссылки.
* **HTML** отображает исходную разметку.
* **Обычный текст** отображает содержимое точно так, как вы его ввели, и не интерпретирует никакую разметку.

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

</details>

<details>

<summary>Карты</summary>

Панели карты отображают по одному маркеру на каждую строку. Запросы должны возвращать столбец широты и столбец долготы:

{% code title="Последние местоположения транспортных средств" overflow="wrap" %}

```sql
С device_owner AS (
  SELECT DISTINCT ON (o.device_id) o.device_id, o.object_label
  FROM raw_business_data.objects o
  WHERE o.is_deleted IS NOT TRUE
  ORDER BY o.device_id, o.object_id
)
SELECT DISTINCT ON (t.device_id)
  d.object_label,
  t.latitude / 1e7 AS latitude,
  t.longitude / 1e7 AS longitude
FROM raw_telematics_data.tracking_data_core t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.device_time >= NOW() - INTERVAL '24 hours'
  AND t.latitude <> 0 AND t.longitude <> 0
ORDER BY t.device_id, t.device_time DESC;
```

{% endcode %}

`DISTINCT ON` с соответствующим `ORDER BY` оставляет по одной строке на устройство, самую новую. Без него запрос отображает каждую историческую точку, которую устройство когда-либо отправляло.

Dashboard Studio автоматически определяет столбцы координат, когда они используют распространенные названия, такие как `latitude`, `lat`, или `gps_lat` для latitude и `долгота`, `lon`, или `lng` для долготы. Если ваши столбцы называются иначе, выберите их вручную в Visualization Settings.

Координаты должны быть в десятичных градусах. Если таблица хранит их как масштабированные целые числа, разделите на `1e7` как показано выше. Любые другие столбцы, которые возвращает запрос, отображаются во всплывающем окне маркера.

</details>

Отчеты следуют тем же структурным правилам, что и запросы визуализации в панелях мониторинга. Поскольку один оператор одновременно обеспечивает работу таблицы данных, диаграммы и карты местоположения, вам может потребоваться объединить столбцы, которые в панели мониторинга были бы записаны как отдельные запросы панелей. Например, запрос панели столбчатой диаграммы, возвращающий два столбца, недостаточен для отчета, которому также нужны GPS-координаты для карты местоположения. Включите все необходимые столбцы для каждого компонента в одном операторе. Основная логика фильтрации и JOIN остается той же, что и в запросах панели; расширить нужно только предложение SELECT.

### Как писать SQL для отчетов

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

#### Требования к столбцам для каждого компонента

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

| Компонент            | Обязательные столбцы                                                              | Примечания                                                  |
| -------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Таблица данных       | Любые столбцы                                                                     | Все возвращаемые столбцы отображаются как столбцы таблицы   |
| График               | Как минимум один столбец времени или категории, как минимум один числовой столбец | Столбцы осей выбираются в настройках графика                |
| Карта местоположения | Широта и долгота в десятичных градусах                                            | Dashboard Studio автоматически определяет столбцы координат |

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

#### Объединение компонентов в одном запросе

Запрос, который возвращает только столбцы, необходимые для графика (два столбца: category и value), не может также использоваться для карты местоположения. Вы должны включить все необходимые столбцы вместе.

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

```sql
С device_owner AS (
  SELECT DISTINCT ON (o.device_id) o.device_id, o.object_label
  FROM raw_business_data.objects o
  WHERE o.is_deleted IS NOT TRUE
  ORDER BY o.device_id, o.object_id
)
SELECT
    t.device_id,
    d.object_label,
    t.device_time,
    t.latitude::float / 10000000 AS latitude,
    t.longitude::float / 10000000 AS longitude,
    t.speed::float / 100 AS speed
FROM raw_telematics_data.tracking_data_core t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.device_time >= NOW() - INTERVAL '24 hours'
ORDER BY t.device_time DESC
LIMIT 1000
```

В этом запросе, `device_time` и `speed` служат для диаграммы, `latitude` и `долгота` служат для карты местоположения, а все столбцы отображаются в таблице данных.

{% hint style="info" %}
Сырые телематические таблицы хранят координаты и скорость в виде масштабированных целых чисел. Координаты делятся на 10,000,000 (10⁷), чтобы преобразовать их в десятичные градусы, а скорость делится на 100 (10²), чтобы преобразовать ее в км/ч. Применяйте эти преобразования в любом запросе, который читает из `raw_telematics_data` таблиц.
{% endhint %}

#### Адаптация запросов панелей мониторинга для Отчеты

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

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

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

[Книга SQL-рецептов](/docs/analytics/ru/example-queries.md) содержит готовые к использованию примеры запросов для типовых анализов Автопарк. Рецепты из книги можно адаптировать для Отчеты, добавив столбцы координат там, где требуется карта местоположения. Основная логика WHERE и JOIN переносится напрямую; изменяйте только предложение SELECT, чтобы охватить все необходимые компоненты.

### Как использовать глобальные переменные

Глобальные переменные предоставляют повторно используемые значения в нескольких инструкциях SQL. Определите переменные в **Настройки > Конфигурация > Глобальные переменные**, затем ссылаться на них, используя `${variable_name}` синтаксис.

<figure><img src="https://1999959041-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2Fgit-blob-978e437b2acf31ae191a828fb7babcd8f3f69333%2Fimage%20(14).png?alt=media" alt=""><figcaption></figcaption></figure>

Определяйте переменные для значений, которые периодически изменяются, но остаются одинаковыми для нескольких панелей: диапазонов дат анализа, фильтров по типу транспортного средства или значений порогов. Когда эти значения меняются, обновите определение переменной один раз вместо редактирования отдельных SQL-запросов.

{% code title="Использование переменных диапазона дат" %}

```sql
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as category,
  COUNT(*) as value
ИЗ processed_common_data.trips
WHERE trip_start_time >= '${analysis_start_date}'::date
  AND trip_start_time < '${analysis_end_date}'::date
GROUP BY DATE_TRUNC('day', trip_start_time)
ORDER BY category;
```

{% endcode %}

Переменные хранят текстовые значения. Приведите их к соответствующим типам в SQL: `'${variable_name}'::date` для дат, `'${variable_name}'::integer` для чисел.

Для параметров, специфичных для запроса и часто меняющихся, можно использовать блоки параметров CTE в начале:

```sql
WITH params AS (
  SELECT 
    300 as min_idle_seconds,
    10 as max_idle_speed_kmh,
    '${analysis_start_date}'::date as date_from,
    '${analysis_end_date}'::date as date_to
)

SELECT 
  e.device_id,
  COUNT(*) as idle_count,
  ROUND(SUM(e.duration_sec) / 60.0) as total_idle_minutes
FROM processed_common_data.rule_based_driver_events e
CROSS JOIN params p
WHERE e.event_type = 'Стоит с включенным двигателем_soft'
  AND e.device_time >= p.date_from
  AND e.device_time < p.date_to
  AND e.speed_kmh <= p.max_idle_speed_kmh
  AND e.duration_sec >= p.min_idle_seconds
ГРУППИРОВАТЬ ПО e.device_id
ORDER BY total_idle_minutes DESC;
```

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

### Как объединить метки Объект

`raw_business_data.objects.device_id` не является уникальным. Одно устройство может содержать несколько записей Объект, потому что устройство, переназначенное между объектами, оставляет предыдущие строки. Таблицы фактов, такие как `processed_common_data.trips` зажигание включено `device_id` отдельно, поэтому обычное соединение с `объекты` умножает каждую строку фактов на количество совпадающих записей Объекта. В результате значения счетчиков и сумм оказываются завышенными, и при этом нет ошибки, которая бы об этом сообщила.

Фильтрация по `is_deleted` само по себе недостаточно, потому что через этот фильтр может пройти больше одной записи. Сначала выберите по одной строке для каждого устройства, затем присоедините это:

{% code title="Соединение Объект и метки" %}

```sql
С device_owner AS (
  SELECT DISTINCT ON (o.device_id) o.device_id, o.object_id, o.object_label
  FROM raw_business_data.objects o
  WHERE o.is_deleted IS NOT TRUE
  ORDER BY o.device_id, o.object_id
)
SELECT d.object_label, COUNT(*) AS trips
FROM processed_common_data.trips t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY d.object_label;
```

{% endcode %}

Используйте `LEFT JOIN` а не внутреннего соединения, чтобы устройство без оставшейся записи Объекта все равно отображалось, а не выпадало из результата.

`processed_common_data.rule_based_driver_events` является исключением. Он уже содержит `object_id` и `метка объекта`, а ее координаты указаны в градусах, поэтому ей не нужны ни это соединение, ни `/1e7` конверсия.

### Как получить доступ к схемам IoT Query

IoT Query организует данные в слоях Сырые данные, Трансформация и Инсайт. Слои Сырые данные и Трансформация содержат по две схемы PostgreSQL, а к таблице вы обращаетесь по имени схемы, а не по слою. Выбор правильного слоя экономит время и делает SQL понятнее. Полные сведения о схемах см. в [Обзор схемы IoT Query](/docs/analytics/ru/iot-query/schema-overview.md).

**Слой сырых данных** содержит то, что записали устройства и платформа Navixy, в двух схемах. `raw_telematics_data` содержит данные мониторинга, ввода и состояния: `raw_telematics_data.tracking_data_core` сохраняет каждую GPS-позицию с временными метками, координатами и показаниями датчиков. `raw_business_data` содержит бизнес-сущности, такие как `raw_business_data.objects`, `raw_business_data.Транспорт`, и `raw_business_data.zones`. Используйте слой Сырые данные для анализа на уровне точек, для сырых значений датчиков, а также для меток и атрибутов, которые вы присоединяете к обработанным данным.

**слой преобразования** содержит обработанные сущности в двух схемах. `processed_common_data` содержит преобразования, которые Navixy поддерживает и которые доступны без настройки: `Поездки`, `sensors_data_by_hours`, `события_на_основе_правил_Водитель`, и `input_change_events`. `processed_custom_data` содержит преобразования, которые вы создаете сами в Transformation Builder. Используйте слой Transformation для большинства задач визуализации, потому что он предоставляет структуры, готовые для анализа. См. [Общие преобразования](/docs/analytics/ru/iot-query/schema-overview/transformation-layer/common-transformations.md) для столбцов каждой таблицы.

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

{% hint style="warning" %}
Названия слоев Bronze, Silver и Gold описывают медальонную архитектуру, которой следуют слои. Это не названия схем, и `silver.Поездки` не является таблицей, к которой можно выполнять запросы. Используйте названия схем выше.
{% endhint %}

Справочные таблицы, использующие `schema.table` формат: `processed_common_data.trips`, а не только `Поездки`. Включайте фильтры диапазона дат в предложения WHERE, чтобы ограничить объем сканируемых данных:

{% code title="Всегда фильтруйте по временным диапазонам" %}

```sql
SELECT device_id, COUNT(*) as trip_count
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
ГРУППА ПО device_id;
```

{% endcode %}

Большинство операторов SQL фильтруют по устройству, временному диапазону или и тому и другому. Добавляйте эти фильтры в начале предложений WHERE, чтобы уменьшить объем обрабатываемых данных.

### Единицы измерения в результатах запроса

IoT Query хранит каждое измерение в одной фиксированной единице, а Dashboard Studio отображает все, что возвращает запрос. Оно не преобразует значения в систему измерений, заданную для аккаунта Navixy, как это делает готовое приложение Dashboards. Два пользователя с разными Параметрами видят одни и те же числа на одной и той же панели.

Единица измерения каждого столбца указана в [Обзор схемы IoT Query](/docs/analytics/ru/iot-query/schema-overview.md), и многие столбцы называют его напрямую. `trip_distance_meters` содержит счетчики, `avg_speed` и `max_speed` удерживайте км/ч, и `altitude_start` и `altitude_end` метры над уровнем моря. Проверьте столбец, прежде чем подписать панель.

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

{% code title="Возвращает расстояние в милях, а не в метрах" %}

```sql
SELECT device_id,
       ROUND(SUM(trip_distance_meters) / 1609.344, 1) as "Distance (mi)"
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '7 days'
ГРУППА ПО device_id;
```

{% endcode %}

Разделите метры на 1,609.344 для миль, км/ч на 1.609344 для mph, а метры на 0.3048 для футов.

### Как использовать SQL Editor

Откройте редактор SQL на левой боковой панели в разделе «Инструменты». Используйте его для трех основных целей: проверки логики перед добавлением на панели, изучения схем данных для понимания доступных столбцов и экспорта данных, которым не нужна визуализация.

<figure><img src="https://1999959041-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2Fgit-blob-a893c4f9e1ab3a12f989fe2efdc541a5b0669668%2Fimage%20(15).png?alt=media" alt=""><figcaption></figcaption></figure>

SQL Editor поддерживает несколько вкладок для разных операторов. Пишите SQL во вкладках, выполняйте с помощью кнопки "Execute Query" и просматривайте результаты в таблице ниже. Результаты показывают метрики выполнения (время выполнения, возвращенные строки) и поддерживают сортировку столбцов для быстрого анализа данных.

Экспортируйте результаты в CSV с помощью кнопки "Export CSV". Это работает для разовых отчетов или выгрузок данных для внешнего анализа. В SQL Editor нет ограничения на количество строк результата, в отличие от SQL для визуализации, который должен возвращать сфокусированные наборы данных.

Проверяйте SQL для визуализации в SQL Editor перед добавлением на панели. Напишите выражение, убедитесь, что оно возвращает ожидаемые столбцы и типы данных, затем скопируйте его на вкладку SQL Query в редакторе панели. Этот рабочий процесс позволяет выявить структурные проблемы до настройки параметров визуализации.

Шаблон исследования новых данных:

{% code expandable="true" %}

```sql
-- 1. Изучите структуру таблицы
SELECT * FROM processed_common_data.trips LIMIT 10;

-- 2. Проверьте охват диапазона дат
SELECT 
  MIN(trip_start_time) as earliest,
  MAX(время_начала_поездки) as последний,
  COUNT(*) as total_trips
FROM processed_common_data.trips;

-- 3. Проверка логики фильтрации
SELECT 
  device_id,
  trip_start_time,
  trip_distance_meters
ИЗ processed_common_data.trips
WHERE trip_start_time >= '2024-01-01'
  AND device_id = 12345
ORDER BY trip_start_time;

-- 4. Адаптируйте для визуализации (2 столбца для столбчатой диаграммы)
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as day,
  COUNT(*) as поездки
ИЗ processed_common_data.trips
WHERE trip_start_time >= '2024-01-01'
  AND device_id = 12345
GROUP BY DATE_TRUNC('day', trip_start_time)
ORDER BY day;
```

{% endcode %}

### Распространенные шаблоны SQL

Большинство SQL-запросов для визуализаций следуют похожим шаблонам. Скопируйте эти структуры и настройте фильтры, столбцы и агрегации под ваши конкретные потребности.

<details>

<summary><strong>Подсчеты временных рядов</strong> для мониторинга тенденций</summary>

```sql
SELECT 
  DATE_TRUNC('hour', trip_start_time) as time_bucket,
  COUNT(*) as event_count
ИЗ processed_common_data.trips
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '24 hours'
GROUP BY DATE_TRUNC('hour', trip_start_time)
ORDER BY time_bucket;
```

</details>

<details>

<summary><strong>Рейтинги категорий</strong> для сравнения групп</summary>

```sql
SELECT 
  category_column,
  COUNT(*) as count
FROM schema.table
WHERE filter_conditions
Группа BY category_column
ORDER BY count DESC
LIMIT 15;
```

</details>

<details>

<summary><strong>Расчет метрик</strong> для агрегированной статистики</summary>

```sql
SELECT 
  ROUND(SUM(trip_distance_meters) / 1000.0, 1) as total_distance_km,
  ROUND(AVG(trip_duration_seconds) / 60.0) as avg_duration_minutes,
  COUNT(*) as trip_count
ИЗ processed_common_data.trips
WHERE trip_start_time >= DATE_TRUNC('week', CURRENT_DATE);
```

</details>

<details>

<summary><strong>Отфильтрованные сводки</strong> с несколькими условиями</summary>

```sql
SELECT 
  device_id,
  COUNT(*) as Поездки,
  ROUND(SUM(trip_distance_meters) / 1000.0, 1) as total_km
ИЗ processed_common_data.trips
ГДЕ время_начала_поездки >= '${period_start}'::date
  AND trip_start_time < '${period_end}'::date
  И поездка_distance_meters >= 5000
  AND trip_duration_seconds >= 600
ГРУППИРОВАТЬ ПО device_id
HAVING COUNT(*) >= 5
ORDER BY total_km DESC;
```

</details>

### Что делать, когда SQL не выполняется

Ошибки выполнения делятся на три категории: структурные несоответствия требованиям визуализации, синтаксические ошибки SQL или фильтры, которые не возвращают данные.

#### **Несоответствия структуры столбцов**

Это происходит, когда результаты не соответствуют ожиданиям визуализации. Если вы выбрали столбчатую диаграмму, а ваш SQL возвращает три столбца, Dashboard Studio не может ее отобразить. Проверьте раздел Dataset Requirements на вкладке SQL Query. Для столбчатой диаграммы нужны ровно два столбца (category, value), поэтому скорректируйте ваш раздел SELECT:

```sql
-- Неверно: три столбца
SELECT device_id, trip_start_time, COUNT(*) FROM processed_common_data.trips GROUP BY device_id, trip_start_time;

-- Правильно: два столбца
SELECT device_id, COUNT(*) as trips FROM processed_common_data.trips GROUP BY device_id;
```

#### **Синтаксические ошибки SQL**

Показывайте конкретные сообщения об ошибках. Распространенные проблемы включают отсутствие префиксов схемы (`Поездки` вместо `processed_common_data.trips`), опечатки в именах столбцов или неверное приведение дат. Проверяйте выражения в SQL Editor, чтобы видеть подробные сообщения об ошибках с номерами строк.

#### **Пустые результаты**

Несмотря на успешное выполнение, это указывает на то, что фильтры исключают все данные. Проверьте SQL без предложений WHERE в редакторе SQL, чтобы убедиться, что таблица содержит данные, затем поэтапно добавляйте фильтры, чтобы определить, какое условие исключает ожидаемые результаты.

#### Проблемы с производительностью

Если запросы выполняются медленно или завершаются по тайм-ауту, добавьте фильтры по диапазону дат в предложения WHERE. Операции, сканирующие целые таблицы, обрабатывают миллионы строк без необходимости:

```sql
-- Медленно: без фильтра по дате
SELECT device_id, COUNT(*) FROM processed_common_data.trips GROUP BY device_id;

-- Быстрый: фильтр по диапазону дат
SELECT device_id, COUNT(*) 
ИЗ processed_common_data.trips 
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
ГРУППА ПО device_id;
```

Для получения дополнительных рекомендаций по производительности см. [Как получить доступ к схемам IoT Query](#how-to-access-iot-query-schemas) о лучших практиках фильтрации и выбора схемы.

### Где найти примеры SQL

Этот [Книга SQL-рецептов](/docs/analytics/ru/example-queries.md) предоставляет полные примеры распространенных телематических анализов. Эти рецепты демонстрируют шаблоны для анализа Поездка, расчетов посещений зон, определения простоя и метрик Автопарк. Каждый рецепт включает полное SQL-выражение, объяснение логики и примеры результатов.

Адаптируйте примеры кулинарной книги (Recipe Book) для визуализаций, изменив предложение SELECT так, чтобы оно соответствовало требованиям визуализации. Рецепт, который возвращает подробные записи поездок (trip records), может стать столбчатой диаграммой, если добавить GROUP BY и агрегирование COUNT. Оператор, который вычисляет показатели для каждого транспорт (per-vehicle metrics), может стать стат-толбиком (stat tile), если добавить SUM по всем транспорт.

Вам нужно лишь:

1. Скопируйте примеры из [Книга рецептов](/docs/analytics/ru/example-queries.md) в редактор Dashboard Studio.
2. Проверьте на ваших реальных данных.
3. Проверьте результаты, затем измените предложение SELECT для целевой визуализации.

Основная логика WHERE и JOIN остается прежней; вы изменяете только структуру вывода.

Для подробностей о схеме см.  [Обзор схемы IoT Query](/docs/analytics/ru/iot-query/schema-overview.md). Этот справочник объясняет доступные таблицы, определения столбцов и связи между Сырые данные, Transformation и Insight Слои.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://navixy.com/docs/analytics/ru/dashboard-studio/writing-sql-queries.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
