# Escrevendo consultas SQL

O Dashboard Studio usa SQL para recuperar dados de esquemas IoT Query. Você escreve SQL em dois contextos: editores de painel, onde as instruções alimentam visualizações, e o Editor SQL independente para exploração de dados. Esta página explica como escrever SQL eficaz para ambos os contextos, com ênfase nos requisitos de visualização, já que eles têm restrições estruturais específicas.

### Onde o SQL é usado

O Dashboard Studio oferece dois ambientes SQL para finalidades diferentes. Entender quando usar cada um ajuda você a trabalhar com mais eficiência.

[**Consultas de visualização**](#how-to-write-sql-for-visualizations) alimentam painéis individuais em relatórios. Você escreve essas instruções no **Consulta SQL** guia do editor de painel. Cada painel executa uma instrução que deve retornar dados em uma estrutura específica, correspondente ao tipo de visualização. Essas instruções são executadas quando os relatórios carregam ou são atualizados, portanto o desempenho importa para a experiência do usuário. O SQL de visualização não pode modificar dados; todas as instruções são executadas como operações SELECT somente leitura nos esquemas IoT Query.

**Relatórios** usam a mesma abordagem de SQL de visualização dos painéis do dashboard. Um relatório executa uma consulta que alimenta três visualizações simultaneamente: a tabela de dados, o gráfico e o mapa de localização. A instrução deve retornar todas as colunas necessárias para os três componentes, portanto inclua colunas de coordenadas, tempo e métricas juntas em um único SELECT.

[**Editor SQL**](#how-to-use-the-sql-editor) oferece suporte à exploração e exportação de dados. Acesse o Editor SQL na barra lateral esquerda, em Ferramentas. Escreva qualquer instrução SELECT para examinar a estrutura dos dados, validar suposições ou exportar resultados como CSV. O Editor SQL exibe tabelas completas de resultados com ordenação de colunas e fornece métricas de execução. Use-o para testar a lógica antes de adicionar SQL aos painéis de visualização, ou para extração de dados ad hoc que não precise de visualização.

{% hint style="info" %}
**A principal diferença**: o SQL de visualização deve corresponder a estruturas exatas de colunas, enquanto as instruções no Editor SQL podem retornar qualquer formato de resultado. Teste primeiro a lógica complexa no Editor SQL e depois adapte-a para visualizações.
{% endhint %}

### Como escrever SQL para visualizações

<figure><img src="/files/c718de76a2a173aaf5edc2054d960a9401da7680" alt=""><figcaption></figcaption></figure>

O SQL de visualização deve retornar contagens e tipos de dados específicos de colunas. O Dashboard Studio não pode renderizar um gráfico de barras a partir de três colunas ou um cartão de indicador com dados de texto. Verifique a seção Requisitos do conjunto de dados na guia Consulta SQL para ver exatamente o que a visualização escolhida espera antes de escrever a instrução. A tabela abaixo contém os tipos de visualização compatíveis:

| Visualização                       | Requisito da consulta          | Exemplo                                                           |
| ---------------------------------- | ------------------------------ | ----------------------------------------------------------------- |
| [Cartão de indicador](#stat-tiles) | Valor numérico único           | `SELECT COUNT(*) FROM schema.table`                               |
| [Gráfico de barras](#bar-charts)   | Duas colunas: categoria, valor | `SELECT column1, COUNT(*) FROM schema.table GROUP BY column1`     |
| [Gráfico de pizza](#pie-charts)    | Duas colunas: rótulo, valor    | `SELECT category, SUM(value) FROM schema.table GROUP BY category` |
| [Tabela](#tables)                  | Qualquer coluna                | `SELECT column1, column2, column3 FROM schema.table`              |
| [Texto](#text-panels)              | Nenhuma consulta necessária    | Somente conteúdo Markdown                                         |

<details>

<summary>Cartões de indicador</summary>

Os cartões de indicador exibem valores numéricos únicos. As instruções devem retornar exatamente uma linha com uma coluna numérica:

{% code title="Total de viagens no mês atual" overflow="wrap" %}

```sql
SELECT COUNT(*) as value
FROM silver.trips
WHERE start_time >= DATE_TRUNC('month', CURRENT_DATE);
```

{% endcode %}

{% code title="Distância total percorrida (km)" overflow="wrap" %}

```sql
SELECT SUM(distance_km) as value
FROM silver.trips
WHERE start_time >= CURRENT_DATE - INTERVAL '7 days';
```

{% endcode %}

O nome da coluna não importa; importa apenas que o resultado seja um único valor numérico. O Dashboard Studio exibe esse valor com a formatação que você configurar em Configurações de visualização.

</details>

<details>

<summary>Gráficos de barras</summary>

Os gráficos de barras exigem exatamente duas colunas: categoria (texto ou data) e valor (numérico). A primeira coluna se torna o eixo X, e a segunda se torna a altura das barras:

{% code title="Viagens por tipo de veículo" overflow="wrap" %}

```sql
SELECT 
  vehicle_type as category,
  COUNT(*) as value
FROM silver.trips
WHERE start_time >= DATE_TRUNC('month', CURRENT_DATE)
GROUP BY vehicle_type
ORDER BY value DESC;
```

{% endcode %}

{% code title="Contagem diária de viagens" overflow="wrap" %}

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

{% endcode %}

Use `ORDER BY` para controlar a sequência das barras. Classifique por valor para comparações ranqueadas ou por categoria para progressões de séries temporais.

</details>

<details>

<summary>Gráficos de pizza</summary>

Os gráficos de pizza exigem exatamente duas colunas: rótulo (texto) e valor (numérico). A primeira coluna se torna o rótulo das fatias, e a segunda determina o tamanho das fatias:

{% code title="Distribuição de viagens por zona" %}

```sql
SELECT 
  zone_name as label,
  COUNT(*) as value
FROM silver.zone_visits
WHERE enter_time >= DATE_TRUNC('month', CURRENT_DATE)
GROUP BY zone_name
ORDER BY value DESC
LIMIT 10;
```

{% endcode %}

Adicione cláusulas LIMIT para categorias com muitos valores. Gráficos de pizza com 20 ou mais fatias tornam-se ilegíveis; limite para as 10 a 15 principais categorias.

</details>

<details>

<summary>Tabelas</summary>

As tabelas aceitam qualquer número de colunas com qualquer tipo de dados. Selecione as colunas que você deseja exibir:

{% code title="Detalhes recentes das viagens" %}

```sql
SELECT 
  device_id,
  start_time,
  end_time,
  distance_km,
  duration_minutes,
  max_speed_kmh
FROM silver.trips
WHERE start_time >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY start_time DESC
LIMIT 100;
```

{% endcode %}

Os nomes das colunas se tornam os cabeçalhos da tabela. Use aliases com espaços para cabeçalhos legíveis: `distance_km as "Distance (km)"`.

</details>

<details>

<summary>Painéis de texto</summary>

Os painéis de texto exibem valores de texto únicos ou strings formatadas. As instruções devem retornar uma coluna de texto:

{% code title="Carimbo de data/hora da última atualização dos dados" %}

```sql
SELECT 
  'Last updated: ' || MAX(record_added_at)::text as value
FROM bronze.tracking_data_core;
```

{% endcode %}

</details>

As consultas de relatório seguem as mesmas regras estruturais das consultas de visualização nos painéis do dashboard. Como uma única instrução alimenta simultaneamente a tabela de dados, o gráfico e o mapa de localização, você pode precisar combinar colunas que seriam escritas como consultas separadas de painel em um dashboard. Por exemplo, uma consulta de painel de gráfico de barras que retorna duas colunas não é suficiente para um relatório que também precisa de coordenadas GPS para o mapa de localização. Inclua todas as colunas necessárias para cada componente em uma única instrução. A lógica central de filtragem e JOIN permanece a mesma das consultas de painel; apenas a cláusula SELECT precisa ser mais ampla.

### Como escrever SQL para relatórios

Um relatório executa uma consulta SQL que alimenta três componentes simultaneamente: a tabela de dados, o gráfico e o mapa de localização. Diferentemente dos painéis do dashboard, em que cada painel tem sua própria consulta focada, a consulta de um relatório deve retornar todas as colunas necessárias para cada componente em uma única instrução SELECT.

#### Requisitos de colunas por componente

Cada componente do relatório tem requisitos específicos de colunas. Sua consulta deve atender a todos os componentes que você habilitou.

| Componente          | Colunas necessárias                                                         | Observações                                                          |
| ------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Tabela de dados     | Qualquer coluna                                                             | Todas as colunas retornadas aparecem como colunas da tabela          |
| Gráfico             | Pelo menos uma coluna de tempo ou categoria, pelo menos uma coluna numérica | As colunas dos eixos são selecionadas nas configurações do gráfico   |
| Mapa de localização | Latitude e longitude em graus decimais                                      | O Dashboard Studio detecta automaticamente as colunas de coordenadas |

Como a tabela de dados aceita qualquer coluna, ela não impõe restrições adicionais. O gráfico e o mapa de localização conduzem a maioria das decisões estruturais.

#### Combinando componentes em uma única consulta

Uma consulta que retorna apenas as colunas necessárias para um gráfico (duas colunas: categoria e valor) não pode também alimentar um mapa de localização. Você deve incluir todas as colunas necessárias juntas.

O exemplo a seguir retorna colunas para todos os três componentes: uma coluna de tempo e uma coluna numérica para o gráfico, colunas de coordenadas para o mapa de localização e atributos adicionais que aparecem na tabela de dados.

```sql
SELECT
    t.device_id,
    o.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
JOIN raw_business_data.objects o ON t.device_id = o.device_id
WHERE t.device_time >= NOW() - INTERVAL '24 hours'
ORDER BY t.device_time DESC
LIMIT 1000
```

Nesta consulta, `device_time` e `speed` atendem ao gráfico, `latitude` e `longitude` atendem ao mapa de localização, e todas as colunas aparecem na tabela de dados.

{% hint style="info" %}
As tabelas brutas de telemetria armazenam coordenadas e velocidade como inteiros escalonados. As coordenadas são divididas por 10.000.000 (10⁷) para converter em graus decimais, e a velocidade é dividida por 100 (10²) para converter para km/h. Aplique essas conversões em qualquer consulta que leia de `raw_telematics_data` tabelas.
{% endhint %}

#### Adaptando consultas de painéis do dashboard para relatórios

Qualquer consulta de painel de um dashboard é um ponto de partida válido para um relatório. O ajuste necessário depende de quais componentes você deseja habilitar.

Se a consulta do painel já for uma visualização de tabela que retorna várias colunas, ela pode já incluir tudo o que é necessário. Adicione colunas de coordenadas se o mapa de localização for necessário.

Se a consulta do painel for um gráfico de barras ou um cartão de indicador que retorna resultados agregados, provavelmente ela não terá o nível de detalhe por linha necessário para a tabela de dados e o mapa de localização. Nesse caso, remova a agregação e trabalhe com os dados da camada bruta ou da camada Silver subjacente.

[Recipe Book de SQL](/docs/analytics/pt-br/example-queries.md) contém exemplos de consultas prontos para uso para análises de frota comuns. As receitas do livro podem ser adaptadas para relatórios adicionando colunas de coordenadas quando o mapa de localização for necessário. A lógica central de WHERE e JOIN é transferida diretamente; ajuste apenas a cláusula SELECT para abranger todos os componentes necessários.

### Como usar variáveis globais

As variáveis globais fornecem valores reutilizáveis em várias instruções SQL. Defina variáveis em **Configurações > Configuração > Variáveis globais**e, em seguida, faça referência a elas usando a sintaxe `${variable_name}` .

<figure><img src="/files/4a963b35482d19669afc0666404e07b3b7e0e7e5" alt=""><figcaption></figcaption></figure>

Defina variáveis para valores que mudam periodicamente, mas permanecem consistentes em vários painéis: intervalos de datas de análise, filtros de tipo de veículo ou valores de limite. Quando esses valores mudarem, atualize a definição da variável uma única vez, em vez de editar instruções SQL individuais.

{% code title="Usando variáveis de intervalo de datas" %}

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

{% endcode %}

As variáveis armazenam valores de texto. Faça o cast para os tipos apropriados em SQL: `'${variable_name}'::date` para datas, `'${variable_name}'::integer` para números.

Para parâmetros específicos da instrução que mudam com frequência, você pode usar blocos de parâmetros CTE no início:

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

SELECT 
  device_id,
  COUNT(*) as idle_count,
  SUM(duration_minutes) as total_idle_minutes
FROM silver.idle_events e
CROSS JOIN params p
WHERE e.event_time >= p.date_from
  AND e.event_time < p.date_to
  AND e.speed_kmh <= p.max_idle_speed_kmh
  AND e.duration_minutes >= p.min_idle_minutes
GROUP BY device_id
ORDER BY total_idle_minutes DESC;
```

Esse padrão combina variáveis globais (intervalos de datas) com parâmetros específicos da instrução (limites), mantendo todos os valores ajustáveis no topo para facilitar a manutenção.

### Como acessar esquemas IoT Query

O IoT Query organiza os dados em camadas Raw data, Transformation e Insight. Entender qual camada usar economiza tempo e melhora a clareza do SQL. Para detalhes completos do esquema, consulte a [Visão geral do esquema IoT Query](https://www.navixy.com/docs/analytics/iotquery/schema-overview).

**Camada de dados brutos** contém pontos de rastreamento brutos dos dispositivos: `bronze.tracking_data_core` armazena cada posição GPS com carimbos de data/hora, coordenadas e leituras de sensores. Use Raw data para análises em nível de ponto ou quando precisar de valores brutos de sensores que não foram processados nas camadas superiores.

**camada de transformação** fornece entidades processadas: `silver.trips` agrega pontos de rastreamento em registros de viagem com horários de início/fim, distância e duração. `silver.zone_visits` registra quando os dispositivos entram e saem de geocercas. `silver.idle_events` identifica períodos em que os veículos permanecem parados com o motor ligado. Use Transformation para a maioria das necessidades de visualização, pois ela fornece estruturas prontas para análise.

**Camada Insight** oferece métricas pré-agregadas e modelos dimensionais para análises complexas. Use Insight para estatísticas de toda a frota ou análises multidimensionais que exigiriam junções complexas com tabelas Silver.

Referencie tabelas usando o formato `schema.table` : `silver.trips`e não apenas `trips`. Inclua filtros de intervalo de datas nas cláusulas WHERE para limitar os dados analisados:

{% code title="Sempre filtre por intervalos de tempo" %}

```sql
SELECT device_id, COUNT(*) as trip_count
FROM silver.trips
WHERE start_time >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY device_id;
```

{% endcode %}

A maioria das instruções SQL filtra por dispositivo, intervalo de tempo ou ambos. Adicione esses filtros cedo nas cláusulas WHERE para reduzir o volume de dados processado.

### Como usar o Editor SQL

Acesse o Editor SQL na barra lateral esquerda, em Ferramentas. Use-o para três finalidades principais: testar a lógica antes de adicionar aos painéis, explorar esquemas de dados para entender as colunas disponíveis e exportar dados que não precisam de visualização.

<figure><img src="/files/df5ff8ac29e587df491eb9115b0ceb48867ff521" alt=""><figcaption></figcaption></figure>

O Editor SQL oferece suporte a várias abas para diferentes instruções. Escreva SQL nas abas, execute com o botão "Executar consulta" e visualize os resultados na tabela abaixo. Os resultados mostram métricas de execução (tempo de execução, linhas retornadas) e oferecem ordenação de colunas para uma análise rápida dos dados.

Exporte os resultados como CSV usando o botão "Exportar CSV". Isso funciona para relatórios ad hoc ou extrações de dados para análise externa. O Editor SQL não tem limite de linhas de resultado, ao contrário do SQL de visualização, que deve retornar conjuntos de dados focados.

Teste o SQL de visualização no Editor SQL antes de adicioná-lo aos painéis. Escreva a instrução, verifique se ela retorna as colunas e os tipos de dados esperados e, em seguida, copie-a para a guia Consulta SQL do editor de painel. Esse fluxo de trabalho detecta problemas estruturais antes que você configure as definições de visualização.

Padrão de exploração para novos dados:

{% code expandable="true" %}

```sql
-- 1. Examine a estrutura da tabela
SELECT * FROM silver.trips LIMIT 10;

-- 2. Verifique a cobertura do intervalo de datas
SELECT 
  MIN(start_time) as earliest,
  MAX(start_time) as latest,
  COUNT(*) as total_trips
FROM silver.trips;

-- 3. Teste a lógica de filtragem
SELECT 
  device_id,
  start_time,
  distance_km
FROM silver.trips
WHERE start_time >= '2024-01-01'
  AND device_id = 12345
ORDER BY start_time;

-- 4. Adapte para visualização (2 colunas para gráfico de barras)
SELECT 
  DATE_TRUNC('day', start_time)::date as day,
  COUNT(*) as trips
FROM silver.trips
WHERE start_time >= '2024-01-01'
  AND device_id = 12345
GROUP BY DATE_TRUNC('day', start_time)
ORDER BY day;
```

{% endcode %}

### Padrões SQL comuns

A maioria do SQL de visualização segue padrões semelhantes. Copie essas estruturas e ajuste filtros, colunas e agregações para suas necessidades específicas.

<details>

<summary><strong>Contagens de séries temporais</strong> para acompanhar tendências</summary>

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

</details>

<details>

<summary><strong>Classificações por categoria</strong> para comparar grupos</summary>

```sql
SELECT 
  category_column,
  COUNT(*) as count
FROM schema.table
WHERE filter_conditions
GROUP BY category_column
ORDER BY count DESC
LIMIT 15;
```

</details>

<details>

<summary><strong>Cálculos de métricas</strong> para estatísticas agregadas</summary>

```sql
SELECT 
  SUM(distance_km) as total_distance,
  AVG(duration_minutes) as avg_duration,
  COUNT(*) as trip_count
FROM silver.trips
WHERE start_time >= DATE_TRUNC('week', CURRENT_DATE);
```

</details>

<details>

<summary><strong>Resumos filtrados</strong> com múltiplas condições</summary>

```sql
SELECT 
  device_id,
  COUNT(*) as trips,
  SUM(distance_km) as total_km
FROM silver.trips
WHERE start_time >= '${period_start}'::date
  AND start_time < '${period_end}'::date
  AND distance_km >= 5
  AND duration_minutes >= 10
GROUP BY device_id
HAVING COUNT(*) >= 5
ORDER BY total_km DESC;
```

</details>

### O que fazer quando o SQL falha

Falhas de execução se enquadram em três categorias: incompatibilidades estruturais com os requisitos de visualização, erros de sintaxe SQL ou filtros que não retornam dados.

#### **Incompatibilidades na estrutura das colunas**

Ocorrem quando os resultados não correspondem às expectativas da visualização. Se você selecionou um gráfico de barras, mas seu SQL retorna três colunas, o Dashboard Studio não consegue renderizá-lo. Verifique Requisitos do conjunto de dados na guia Consulta SQL. O gráfico de barras precisa de exatamente duas colunas (categoria, valor), então ajuste sua cláusula SELECT:

```sql
-- Errado: três colunas
SELECT device_id, start_time, COUNT(*) FROM silver.trips GROUP BY device_id, start_time;

-- Correto: duas colunas
SELECT device_id, COUNT(*) as trips FROM silver.trips GROUP BY device_id;
```

#### **Erros de sintaxe SQL**

Exibem mensagens de erro específicas. Problemas comuns incluem prefixos de esquema ausentes (`trips` em vez de `silver.trips`), erros de digitação em nomes de colunas ou cast de data incorreto. Teste as instruções no Editor SQL para ver mensagens de erro detalhadas com números de linha.

#### **Resultados vazios**

Apesar da execução bem-sucedida, indicam que os filtros excluem todos os dados. Teste o SQL sem cláusulas WHERE no Editor SQL para verificar se a tabela contém dados e, em seguida, adicione filtros gradualmente para identificar qual condição está excluindo os resultados esperados.

#### Problemas de desempenho

Se as instruções forem executadas lentamente ou atingirem timeout, adicione filtros de intervalo de datas às cláusulas WHERE. Operações que verificam tabelas inteiras processam milhões de linhas desnecessariamente:

```sql
-- Lento: sem filtro de data
SELECT device_id, COUNT(*) FROM silver.trips GROUP BY device_id;

-- Rápido: filtro de intervalo de datas
SELECT device_id, COUNT(*) 
FROM silver.trips 
WHERE start_time >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY device_id;
```

Para orientações adicionais de desempenho, consulte [Como acessar esquemas IoT Query](#how-to-access-iot-query-schemas) para obter boas práticas sobre filtragem e seleção de esquemas.

### Onde encontrar exemplos de SQL

O [Recipe Book de SQL](/docs/analytics/pt-br/example-queries.md) fornece exemplos completos para análises telemáticas comuns. Essas receitas demonstram padrões para análise de viagens, cálculos de visitas a zonas, detecção de ociosidade e métricas de frota. Cada receita inclui a instrução SQL completa, a explicação da lógica e resultados de exemplo.

Adapte os exemplos do Recipe Book para visualizações ajustando a cláusula SELECT para corresponder aos requisitos de visualização. Uma receita que retorna registros detalhados de viagens pode se tornar um gráfico de barras adicionando GROUP BY e agregação COUNT. Uma instrução que calcula métricas por veículo pode se tornar um cartão de indicador adicionando SUM em todos os veículos.

Você só precisa:

1. Copiar exemplos de [Recipe Book](/docs/analytics/pt-br/example-queries.md) para o Editor do Dashboard Studio.
2. Testar com seus dados reais.
3. Verificar os resultados e, em seguida, modificar a cláusula SELECT para a visualização desejada.

A lógica central de WHERE e JOIN permanece a mesma; você ajusta apenas a estrutura de saída.

Para detalhes do esquema, consulte a [Visão geral do esquema IoT Query](https://www.navixy.com/docs/analytics/iotquery/schema-overview). Esta referência explica as tabelas disponíveis, as definições de colunas e as relações entre as camadas Raw data, Transformation e Insight.


---

# Agent Instructions: 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:

```
GET https://navixy.com/docs/analytics/pt-br/dashboard-studio/writing-sql-queries.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
