> 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/id/dashboard-studio/writing-sql-queries.md).

# Menulis kueri SQL

Tulis kueri PostgreSQL yang dioptimalkan untuk visualisasi Dashboard Studio. Pelajari pola akses data, pemilihan lapisan, dan praktik terbaik performa

Dashboard Studio menggunakan SQL untuk mengambil data dari skema IoT Query. Anda menulis SQL dalam dua konteks: editor panel, tempat pernyataan mendukung visualisasi, dan SQL Editor mandiri untuk eksplorasi data. Halaman ini menjelaskan cara menulis SQL yang efektif untuk kedua konteks, dengan penekanan pada persyaratan visualisasi karena memiliki kendala struktural tertentu.

### Tempat SQL digunakan

Dashboard Studio menyediakan dua lingkungan SQL untuk tujuan yang berbeda. Memahami kapan menggunakan masing-masing membantu Anda bekerja lebih efisien.

[**Kueri visualisasi**](#how-to-write-sql-for-visualizations) mendukung panel individual dalam Laporan. Anda menulis pernyataan ini di tab editor panel. Setiap panel menjalankan satu pernyataan yang harus mengembalikan data dalam struktur tertentu yang sesuai dengan jenis visualisasi. Pernyataan ini dieksekusi saat Laporan dimuat atau disegarkan, jadi kinerja penting bagi pengalaman pengguna. SQL visualisasi tidak dapat mengubah data; semua pernyataan berjalan sebagai operasi SELECT hanya-baca terhadap skema IoT Query. **Kueri SQL** gunakan pendekatan SQL visualisasi yang sama seperti panel dashboard. Sebuah Laporan menjalankan satu kueri yang mendukung tiga tampilan sekaligus: tabel data, grafik, dan peta lokasi. Pernyataan tersebut harus mengembalikan semua kolom yang diperlukan di ketiga komponen, jadi sertakan kolom koordinat, waktu, dan metrik bersama-sama dalam satu SELECT.

**Laporan** SQL Editor

[**mendukung eksplorasi data dan ekspor. Akses SQL Editor dari bilah sisi kiri di bawah Tools. Tulis pernyataan SELECT apa pun untuk memeriksa struktur data, memvalidasi asumsi, atau mengekspor hasil sebagai CSV. SQL Editor menampilkan tabel hasil lengkap dengan pengurutan kolom dan menyediakan metrik eksekusi. Gunakan ini untuk menguji logika sebelum menambahkan SQL ke panel visualisasi, atau untuk ekstraksi data ad hoc yang tidak memerlukan visualisasi.**](#how-to-use-the-sql-editor) Perbedaan utamanya

{% hint style="info" %}
**Perbedaan utama**: SQL visualisasi harus sesuai dengan struktur kolom yang tepat, sedangkan pernyataan di SQL Editor dapat mengembalikan format hasil apa pun. Uji logika kompleks di SQL Editor terlebih dahulu, lalu sesuaikan untuk visualisasi.
{% endhint %}

### Cara menulis SQL untuk visualisasi

<figure><img src="https://1696125515-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 visualisasi harus mengembalikan jumlah kolom dan tipe data tertentu. Dashboard Studio tidak dapat merender diagram batang dari tiga kolom atau kartu statistik dari data teks. Periksa bagian Persyaratan set data di tab Kueri SQL untuk melihat secara tepat apa yang diharapkan visualisasi yang Anda pilih sebelum menulis pernyataan tersebut. Tabel di bawah ini berisi tipe visualisasi yang didukung:

| Visualisasi                      | Persyaratan kueri          | Contoh                                                             |
| -------------------------------- | -------------------------- | ------------------------------------------------------------------ |
| [Kartu statistik](#stat-tiles)   | Nilai numerik tunggal      | `SELECT COUNT(*) FROM schema.table`                                |
| [Diagram batang](#bar-charts)    | Dua kolom: kategori, nilai | `PILIH kolom1, HITUNG(*) DARI skema.tabel GRUP DENGAN kolom1`      |
| [Diagram lingkaran](#pie-charts) | Dua kolom: label, nilai    | `PILIH kategori, JUMLAH(nilai) DARI skema.tabel GROUP BY kategori` |
| [Tabel](#tables)                 | Kolom apa pun              | `SELECT column1, column2, column3 FROM schema.table`               |
| [Teks](#text-panels)             | Tidak diperlukan kueri     | Markdown, HTML, atau teks biasa                                    |
| [Peta](#maps)                    | Kolom lintang dan bujur    | `SELECT latitude, longitude FROM schema.table`                     |

<details>

<summary>Tile statistik</summary>

Ubin statistik menampilkan nilai numerik tunggal. Pernyataan harus mengembalikan tepat satu baris dengan satu kolom numerik:

{% code title="Total perjalanan pada bulan berjalan" overflow="wrap" %}

```sql
SELECT COUNT(*) as value
FROM processed_common_data.perjalanan
WHERE trip_start_time >= DATE_TRUNC('month', CURRENT_DATE);
```

{% endcode %}

{% code title="Total jarak tempuh (km)" overflow="wrap" %}

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

{% endcode %}

Nama kolom tidak penting, yang penting hasilnya adalah satu nilai numerik. Dashboard Studio menampilkan nilai ini dengan pemformatan yang Anda konfigurasikan di pengaturan visualisasi.

</details>

<details>

<summary>Grafik batang</summary>

Diagram batang memerlukan tepat dua kolom: kategori (teks atau tanggal) dan nilai (angka). Kolom pertama menjadi sumbu X, kolom kedua menjadi tinggi batang:

{% code title="Perjalanan per pelacak" overflow="wrap" %}

```sql
DENGAN device_owner SEBAGAI (
  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
  URUTKAN BERDASARKAN o.device_id, o.object_id
)
SELECT 
  d.object_label sebagai kategori,
  COUNT(*) sebagai nilai
DARI processed_common_data.perjalanan t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.trip_start_time >= DATE_TRUNC('month', CURRENT_DATE)
Kelompok berdasarkan d.object_label
ORDER BY value DESC;
```

{% endcode %}

Kelompokkan berdasarkan kolom teks. `raw_business_data.vehicles.vehicle_type` menyimpan kode bilangan bulat, bukan nama, sehingga pengelompokan berdasarkan kode tersebut memberi label pada batang `1`, `2`, `3`.

Itu `pemilik perangkat` blok di bagian atas tidak bersifat opsional setiap kali Anda menggabungkan label Pelacak ke Perjalanan atau peristiwa. Lihat [Cara menggabungkan label Pelacak](#how-to-join-object-labels).

{% code title="Jumlah perjalanan harian" overflow="wrap" %}

```sql
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as category,
  COUNT(*) sebagai nilai
FROM processed_common_data.perjalanan
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
Kelompok berdasarkan DATE_TRUNC('day', trip_start_time)
ORDER BY category;
```

{% endcode %}

Gunakan `ORDER BY` untuk mengontrol urutan batang. Urutkan berdasarkan nilai untuk perbandingan berperingkat atau berdasarkan kategori untuk progresi deret waktu.

</details>

<details>

<summary>Grafik pai</summary>

Diagram pai memerlukan tepat dua kolom: label (teks) dan nilai (numerik). Kolom pertama menjadi label irisan, kolom kedua menentukan ukuran irisan:

{% code title="Perjalanan berdasarkan zona awal" %}

```sql
SELECT 
  start_zone sebagai label,
  COUNT(*) sebagai nilai
FROM processed_common_data.perjalanan
WHERE trip_start_time >= DATE_TRUNC('month', CURRENT_DATE)
  AND start_zone IS NOT NULL
Kelompok berdasarkan start_zone
ORDER BY value DESC
LIMIT 10;
```

{% endcode %}

Tambahkan klausa LIMIT untuk kategori dengan banyak nilai. Diagram pai dengan 20+ irisan menjadi sulit dibaca; batasi hingga 10-15 kategori teratas.

</details>

<details>

<summary>Tabel</summary>

Tabel menerima sejumlah kolom apa pun dengan tipe data apa pun. Pilih kolom yang ingin Anda tampilkan:

{% code title="Detail perjalanan terbaru" %}

```sql
SELECT 
  device_id,
  trip_start_time,
  trip_end_time,
  ROUND(trip_distance_meters / 1000.0, 1) as distance_km,
  ROUND(trip_duration_seconds / 60.0) as duration_minutes,
  max_speed
FROM processed_common_data.perjalanan
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY trip_start_time DESC
LIMIT 100;
```

{% endcode %}

Nama kolom menjadi header tabel. Gunakan alias dengan spasi untuk header yang mudah dibaca: `ROUND(trip_distance_meters / 1000.0, 1) as "Jarak (km)"`.

</details>

<details>

<summary>Panel teks</summary>

Panel teks menampilkan konten Markdown, HTML, atau teks biasa. Panel ini tidak menjalankan kueri SQL.

Pada **Konten** tab, pilih opsi di bawah **Mode konten**:

* **Markdown** (default) mendukung pemformatan seperti judul dan tautan.
* **HTML** merender markup mentah.
* **Teks biasa** menampilkan konten persis seperti yang Anda masukkan dan tidak menafsirkan markup apa pun.

Gunakan panel teks untuk judul bagian, instruksi, atau konteks di samping visualisasi data Anda.

</details>

<details>

<summary>Peta</summary>

Panel peta menampilkan satu penanda per baris. Pernyataan harus mengembalikan kolom lintang dan kolom bujur:

{% code title="Posisi kendaraan terbaru" overflow="wrap" %}

```sql
DENGAN device_owner SEBAGAI (
  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
  URUTKAN BERDASARKAN o.device_id, o.object_id
)
SELECT DISTINCT ON (t.device_id)
  d.label_pelacak,
  t.latitude / 1e7 AS latitude,
  t.longitude / 1e7 AS longitude
DARI raw_telematics_data.tracking_data_core t
LEFT JOIN device_owner d ON d.device_id = t.device_id
DI MANA t.device_time >= NOW() - INTERVAL '24 hours'
  DAN t.latitude <> 0 DAN t.longitude <> 0
URUTKAN BERDASARKAN t.device_id, t.device_time DESC;
```

{% endcode %}

`DISTINCT ON` dengan yang cocok `ORDER BY` mempertahankan satu baris per perangkat, yang terbaru. Tanpanya, kueri akan menampilkan setiap titik historis yang pernah dikirim perangkat.

Dashboard Studio mendeteksi kolom koordinat secara otomatis ketika kolom tersebut menggunakan nama umum seperti `latitude`, `lat`, atau `gps_lat` untuk lintang dan `bujur`, `lon`, atau `lng` untuk bujur. Jika kolom Anda menggunakan nama yang berbeda, pilih secara manual di Pengaturan visualisasi.

Koordinat harus dalam derajat desimal. Jika tabel menyimpannya sebagai bilangan bulat berskala, bagi dengan `1e7` seperti ditunjukkan di atas. Kolom lain apa pun yang dikembalikan pernyataan akan muncul di popup penanda.

</details>

Query laporan mengikuti aturan struktural yang sama seperti query visualisasi dalam panel dasbor. Karena satu pernyataan mendukung tabel data, bagan, dan peta lokasi secara bersamaan, Anda mungkin perlu menggabungkan kolom yang akan ditulis sebagai query panel terpisah di dasbor. Misalnya, query panel bagan batang yang mengembalikan dua kolom tidak cukup untuk laporan yang juga memerlukan koordinat GPS untuk peta lokasi. Sertakan semua kolom yang diperlukan untuk setiap komponen dalam satu pernyataan. Logika pemfilteran inti dan JOIN tetap sama seperti pada query panel; hanya klausa SELECT yang perlu mencakup lebih banyak kolom.

### Cara menulis SQL untuk laporan

Sebuah laporan menjalankan satu query SQL yang sekaligus mendukung tiga komponen: tabel data, bagan, dan peta lokasi. Tidak seperti panel dasbor, yang setiap panel memiliki query terfokusnya sendiri, query laporan harus mengembalikan semua kolom yang diperlukan untuk setiap komponen dalam satu pernyataan SELECT.

#### Persyaratan kolom per komponen

Setiap komponen laporan memiliki persyaratan kolom tertentu. Query Anda harus memenuhi semua komponen yang telah Anda aktifkan.

| Komponen    | Kolom yang diperlukan                                                    | Catatan                                                       |
| ----------- | ------------------------------------------------------------------------ | ------------------------------------------------------------- |
| Tabel data  | Kolom apa pun                                                            | Semua kolom yang dikembalikan akan tampil sebagai kolom tabel |
| Grafik      | Setidaknya satu kolom waktu atau kategori, setidaknya satu kolom numerik | Kolom sumbu dipilih dalam pengaturan grafik                   |
| Peta lokasi | Lintang dan bujur dalam derajat desimal                                  | Dashboard Studio mendeteksi kolom koordinat secara otomatis   |

Karena tabel data menerima kolom apa pun, tabel ini tidak memberlakukan batasan tambahan. Grafik dan peta lokasi menentukan sebagian besar keputusan struktural.

#### Menggabungkan komponen dalam satu kueri

Kueri yang hanya mengembalikan kolom yang diperlukan untuk grafik (dua kolom: kategori dan nilai) tidak dapat sekaligus digunakan untuk peta lokasi. Anda harus menyertakan semua kolom yang diperlukan bersama-sama.

Contoh berikut mengembalikan kolom untuk ketiga komponen: kolom waktu dan kolom numerik untuk grafik, kolom koordinat untuk peta lokasi, dan atribut tambahan yang muncul di tabel data.

```sql
DENGAN device_owner SEBAGAI (
  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
  URUTKAN BERDASARKAN o.device_id, o.object_id
)
SELECT
    t.device_id,
    d.label_pelacak,
    t.device_time,
    t.latitude::float / 10000000 AS latitude,
    t.longitude::float / 10000000 AS longitude,
    t.speed::float / 100 AS speed
DARI raw_telematics_data.tracking_data_core t
LEFT JOIN device_owner d ON d.device_id = t.device_id
DI MANA t.device_time >= NOW() - INTERVAL '24 hours'
ORDER BY t.device_time DESC
LIMIT 1000
```

Dalam kueri ini, `device_time` dan `kecepatan` menyajikan grafik, `latitude` dan `bujur` menyajikan peta lokasi, dan semua kolom muncul di tabel data.

{% hint style="info" %}
Tabel telematika mentah menyimpan koordinat dan kecepatan sebagai bilangan bulat berskala. Koordinat dibagi 10.000.000 (10⁷) untuk dikonversi menjadi derajat desimal, dan kecepatan dibagi 100 (10²) untuk dikonversi menjadi km/jam. Terapkan konversi ini dalam kueri apa pun yang membaca dari `raw_telematics_data` tabel.
{% endhint %}

#### Menyesuaikan kueri panel dasbor untuk laporan

Setiap kueri panel dari dasbor merupakan titik awal yang valid untuk laporan. Penyesuaian yang diperlukan bergantung pada komponen mana yang ingin Anda aktifkan.

Jika kueri panel sudah merupakan visualisasi tabel yang menampilkan beberapa kolom, kueri tersebut mungkin sudah mencakup semua yang diperlukan. Tambahkan kolom koordinat jika peta lokasi diperlukan.

Jika kueri panel adalah diagram batang atau kueri ubin statistik yang menampilkan hasil teragregasi, kemungkinan kueri tersebut tidak memiliki detail tingkat baris yang diperlukan untuk tabel data dan peta lokasi. Dalam kasus itu, hapus agregasinya dan gunakan tabel lapisan data mentah atau lapisan transformasi yang mendasarinya.

[Buku resep SQL](/docs/analytics/id/example-queries.md) berisi contoh kueri siap pakai untuk analisis Armada umum. Resep dari buku ini dapat disesuaikan untuk Laporan dengan menambahkan kolom koordinat saat peta lokasi diperlukan. Logika inti WHERE dan JOIN dapat langsung diterapkan; sesuaikan hanya klausa SELECT untuk mencakup semua komponen yang diperlukan.

### Cara menggunakan variabel global

Variabel global menyediakan nilai yang dapat digunakan kembali di beberapa pernyataan SQL. Definisikan variabel di **Pengaturan > Konfigurasi > Variabel global**, lalu referensikan dengan `${variable_name}` sintaks.

<figure><img src="https://1696125515-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>

Definisikan variabel untuk nilai yang berubah secara berkala tetapi tetap konsisten di beberapa panel: rentang tanggal analisis, filter jenis kendaraan, atau nilai ambang batas. Saat nilai-nilai ini berubah, perbarui definisi variabel satu kali alih-alih menyunting pernyataan SQL satu per satu.

{% code title="Menggunakan variabel rentang tanggal" %}

```sql
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as category,
  COUNT(*) sebagai nilai
FROM processed_common_data.perjalanan
WHERE trip_start_time >= '${analysis_start_date}'::date
  AND trip_start_time < '${analysis_end_date}'::date
Kelompok berdasarkan DATE_TRUNC('day', trip_start_time)
ORDER BY category;
```

{% endcode %}

Variabel menyimpan nilai teks. Ubah tipe mereka ke jenis yang sesuai dalam SQL: `'${variable_name}'::date` untuk tanggal, `'${variable_name}'::integer` untuk angka.

Untuk parameter khusus pernyataan yang sering berubah, Anda dapat menggunakan blok parameter CTE di awal:

```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
DARI processed_common_data.rule_based_driver_events e
CROSS JOIN params p
WHERE e.event_type = 'Idle_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
Kelompok berdasarkan e.device_id
ORDER BY total_idle_minutes DESC;
```

Pola ini menggabungkan variabel global (rentang tanggal) dengan parameter khusus per pernyataan (ambang batas), sehingga semua nilai yang dapat disesuaikan tetap berada di bagian atas untuk Pemeliharaan yang mudah.

### Cara menggabungkan label Pelacak

`raw_business_data.objects.device_id` Tidak unik. Satu perangkat dapat membawa beberapa catatan pelacak, karena perangkat yang dialihkan antar pelacak meninggalkan baris-baris sebelumnya. Tabel fakta seperti `processed_common_data.perjalanan` kontak menyala `device_id` sendiri, jadi gabungan biasa ke `objek` Mengalikan setiap baris fakta dengan jumlah rekaman Pelacak yang cocok. Hitungan dan jumlah kemudian menjadi terlalu tinggi, tanpa galat yang memberi tahu Anda.

Penyaringan pada `is_deleted` tidak cukup dengan sendirinya, karena lebih dari satu catatan dapat lolos dari filter tersebut. Pilih satu baris per perangkat terlebih dahulu, lalu gabungkan itu:

{% code title="Gabungan pelacak-label" %}

```sql
DENGAN device_owner SEBAGAI (
  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
  URUTKAN BERDASARKAN o.device_id, o.object_id
)
SELECT d.object_label, COUNT(*) AS trips
DARI processed_common_data.perjalanan t
LEFT JOIN device_owner d ON d.device_id = t.device_id
WHERE t.trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
Kelompok berdasarkan d.object_label;
```

{% endcode %}

Gunakan `LEFT JOIN` bukannya penggabungan dalam, sehingga perangkat yang tidak memiliki catatan Pelacak yang masih ada tetap muncul alih-alih hilang dari hasil.

`processed_common_data.rule_based_Supir_events` adalah pengecualian. Itu sudah memuat `id_objek` dan `label Pelacak`, dan koordinatnya dalam derajat, jadi tidak memerlukan penggabungan ini maupun `/1e7` konversi.

### Cara mengakses skema IoT Query

IoT Query mengorganisasi data dalam lapisan data mentah, transformasi, dan wawasan. Lapisan data mentah dan transformasi masing-masing menyimpan dua skema PostgreSQL, dan Anda mereferensikan tabel berdasarkan nama skemanya, bukan berdasarkan lapisan. Memilih lapisan yang tepat menghemat waktu dan menjaga SQL tetap jelas. Untuk detail skema lengkap, lihat [Ikhtisar skema IoT Query](/docs/analytics/id/iot-query/schema-overview.md).

**Lapisan data mentah** memuat apa yang dicatat oleh perangkat dan platform Navixy, dalam dua skema. `raw_telematics_data` berisi data pelacakan, input, dan status: `raw_telematics_data.tracking_data_core` menyimpan setiap posisi GPS beserta stempel waktu, koordinat, dan pembacaan sensor. `raw_business_data` menampung entitas bisnis seperti `raw_business_data.objects`, `raw_business_data.kendaraan`, dan `raw_business_data.zones`. Gunakan lapisan data mentah untuk analisis per titik, untuk nilai sensor mentah, dan untuk label serta atribut yang Anda gabungkan ke data yang diproses.

**Lapisan transformasi** Menyimpan entitas yang diproses dalam dua skema. `processed_common_data` Menyimpan transformasi yang dipelihara Navixy, yang tersedia tanpa konfigurasi: `Perjalanan`, `sensors_data_by_hours`, `rule_based_Supir_events`, dan `input_change_events`. `processed_custom_data` menyimpan transformasi yang Anda buat sendiri di Transformation Builder. Gunakan lapisan Transformation untuk sebagian besar kebutuhan visualisasi, karena menyediakan struktur siap analisis. Lihat [Transformasi umum](/docs/analytics/id/iot-query/schema-overview/transformation-layer/common-transformations.md) untuk kolom setiap tabel.

**Lapisan Insight** menyediakan metrik praagregasi dan model dimensional untuk analitik kompleks. Gunakan untuk statistik seluruh armada atau analisis multidimensi yang jika tidak akan memerlukan join kompleks terhadap tabel lapisan Transformation.

{% hint style="warning" %}
Nama lapisan Bronze, Silver, dan Gold menggambarkan arsitektur medallion yang diikuti lapisan-lapisan tersebut. Itu bukan nama skema, dan `silver.Perjalanan` bukan tabel yang dapat Anda kueri. Gunakan nama skema di atas.
{% endhint %}

Rujuk tabel menggunakan `schema.table` format: `processed_common_data.perjalanan`, bukan hanya `Perjalanan`. Sertakan filter rentang tanggal dalam klausa WHERE untuk membatasi data yang dipindai:

{% code title="Selalu filter berdasarkan rentang waktu" %}

```sql
SELECT device_id, COUNT(*) as trip_count
FROM processed_common_data.perjalanan
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
Kelompokkan berdasarkan device_id;
```

{% endcode %}

Sebagian besar pernyataan SQL memfilter berdasarkan perangkat, rentang waktu, atau keduanya. Tambahkan filter ini lebih awal dalam klausa WHERE untuk mengurangi volume data yang diproses.

### Satuan pengukuran dalam hasil kueri

IoT Query menyimpan setiap pengukuran dalam satu satuan tetap, dan Dashboard Studio menampilkan apa pun yang dikembalikan kueri. IoT Query tidak mengonversi nilai ke sistem pengukuran yang ditetapkan pada akun Navixy, seperti yang dilakukan aplikasi Dashboards bawaan. Dua orang dengan Pengaturan akun yang berbeda melihat angka yang sama pada panel yang sama.

Satuan setiap kolom didokumentasikan di [Ikhtisar skema IoT Query](/docs/analytics/id/iot-query/schema-overview.md), dan banyak kolom menyebutkannya secara langsung. `trip_distance_meters` berisi meter, `avg_speed` dan `max_speed` berisi km/jam, dan `altitude_start` dan `altitude_end` berisi meter di atas permukaan laut. Periksa kolom sebelum Anda memberi label pada panel.

Konversikan dalam kueri ketika pembaca Anda bekerja dengan satuan lain, dan tuliskan satuannya dalam alias kolom agar panel menampilkan label yang benar:

{% code title="Mengembalikan jarak dalam mil, bukan meter" %}

```sql
SELECT device_id,
       ROUND(SUM(trip_distance_meters) / 1609.344, 1) as "Jarak (mi)"
FROM processed_common_data.perjalanan
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '7 days'
Kelompokkan berdasarkan device_id;
```

{% endcode %}

Bagi meter dengan 1.609,344 untuk mil, km/jam dengan 1,609344 untuk mph, dan meter dengan 0,3048 untuk kaki.

### Cara menggunakan SQL Editor

Buka SQL Editor dari bilah sisi kiri di bawah Tools. Gunakan ini untuk tiga tujuan utama: menguji logika sebelum menambahkannya ke panel, menjelajahi skema data untuk memahami kolom yang tersedia, dan mengekspor data yang tidak memerlukan visualisasi.

<figure><img src="https://1696125515-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 mendukung beberapa tab untuk pernyataan yang berbeda. Tulis SQL di tab, jalankan dengan tombol "Execute Query", dan lihat hasilnya di tabel di bawah. Hasil menampilkan metrik eksekusi (waktu eksekusi, baris yang dikembalikan) dan mendukung pengurutan kolom untuk pemeriksaan data cepat.

Ekspor hasil sebagai CSV menggunakan tombol "Export CSV". Ini cocok untuk laporan ad hoc atau ekstrak data untuk analisis eksternal. SQL Editor tidak memiliki batas jumlah baris hasil, tidak seperti SQL visualisasi yang seharusnya mengembalikan kumpulan data yang terfokus.

Uji SQL visualisasi di SQL Editor sebelum menambahkannya ke panel. Tulis pernyataannya, verifikasi bahwa pernyataan itu mengembalikan kolom dan tipe data yang diharapkan, lalu salin ke tab SQL Query editor panel. Alur kerja ini menangkap masalah struktural sebelum Anda mengonfigurasi pengaturan visualisasi.

Pola eksplorasi untuk data baru:

{% code expandable="true" %}

```sql
-- 1. Periksa struktur tabel
PILIH * DARI processed_common_data.trips BATASI 10;

-- 2. Periksa cakupan rentang tanggal
SELECT 
  MIN(trip_start_time) sebagai paling awal,
  MAX(trip_start_time) as latest,
  COUNT(*) sebagai total_perjalanan
FROM processed_common_data.Perjalanan;

-- 3. Uji logika penyaringan
SELECT 
  device_id,
  trip_start_time,
  trip_distance_meters
FROM processed_common_data.perjalanan
WHERE trip_start_time >= '2024-01-01'
  AND device_id = 12345
ORDER BY trip_start_time;

-- 4. Sesuaikan untuk visualisasi (2 kolom untuk diagram batang)
SELECT 
  DATE_TRUNC('day', trip_start_time)::date as day,
  COUNT(*) as Perjalanan
FROM processed_common_data.perjalanan
WHERE trip_start_time >= '2024-01-01'
  AND device_id = 12345
Kelompok berdasarkan DATE_TRUNC('day', trip_start_time)
ORDER BY day;
```

{% endcode %}

### Pola SQL umum

Sebagian besar SQL untuk visualisasi mengikuti pola yang serupa. Salin struktur ini dan sesuaikan filter, kolom, dan agregasi sesuai kebutuhan spesifik Anda.

<details>

<summary><strong>Hitungan deret waktu</strong> untuk melacak tren</summary>

```sql
SELECT 
  DATE_TRUNC('hour', trip_start_time) sebagai time_bucket,
  COUNT(*) sebagai event_count
FROM processed_common_data.perjalanan
DENGAN trip_start_time >= CURRENT_DATE - INTERVAL '24 jam'
KELOMPOKKAN BERDASARKAN DATE_TRUNC('hour', trip_start_time)
URUTKAN BERDASARKAN time_bucket;
```

</details>

<details>

<summary><strong>Peringkat kategori</strong> untuk membandingkan kelompok</summary>

```sql
SELECT 
  category_column,
  COUNT(*) sebagai count
DARI schema.table
WHERE kondisi filter
Kelompok BY category_column
ORDER BY count DESC
LIMIT 15;
```

</details>

<details>

<summary><strong>Perhitungan metrik</strong> untuk statistik agregat</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
FROM processed_common_data.perjalanan
WHERE trip_start_time >= DATE_TRUNC('week', CURRENT_DATE);
```

</details>

<details>

<summary><strong>Ringkasan terfilter</strong> dengan beberapa kondisi</summary>

```sql
SELECT 
  device_id,
  COUNT(*) sebagai Perjalanan,
  ROUND(SUM(trip_distance_meters) / 1000.0, 1) as total_km
FROM processed_common_data.perjalanan
WHERE trip_start_time >= '${period_start}'::date
  AND trip_start_time < '${period_end}'::date
  AND trip_distance_meters >= 5000
  AND trip_duration_seconds >= 600
Kelompok berdasarkan device_id
HAVING COUNT(*) >= 5
ORDER BY total_km DESC;
```

</details>

### Apa yang harus dilakukan saat SQL gagal

Kegagalan eksekusi terbagi menjadi tiga kategori: ketidaksesuaian struktural dengan persyaratan visualisasi, galat sintaks SQL, atau filter yang tidak mengembalikan data.

#### **Ketidaksesuaian struktur kolom**

Terjadi ketika hasil tidak cocok dengan ekspektasi visualisasi. Jika Anda memilih diagram batang tetapi SQL Anda mengembalikan tiga kolom, Dashboard Studio tidak dapat merendernya. Periksa Persyaratan dataset di tab Kueri SQL. Diagram batang memerlukan tepat dua kolom (kategori, nilai), jadi sesuaikan klausa SELECT Anda:

```sql
-- Salah: tiga kolom
SELECT device_id, trip_start_time, COUNT(*) FROM processed_common_data.trips GROUP BY device_id, trip_start_time;

-- Benar: dua kolom
PILIH device_id, COUNT(*) sebagai perjalananan dari processed_common_data.trips GROUPKAN berdasarkan device_id;
```

#### **Galat sintaks SQL**

Tampilkan Pesan galat tertentu. Masalah umum meliputi prefix skema yang hilang (`Perjalanan` alih-alih `processed_common_data.perjalanan`), salah ketik pada nama kolom, atau casting tanggal yang salah. Uji pernyataan di SQL Editor untuk melihat pesan galat terperinci dengan nomor baris.

#### **Hasil kosong**

Meskipun eksekusi berhasil, ini menunjukkan bahwa filter mengecualikan semua data. Uji SQL tanpa klausa WHERE di Editor SQL untuk memverifikasi bahwa tabel berisi data, lalu tambahkan filter secara bertahap untuk mengidentifikasi kondisi mana yang mengecualikan hasil yang Anda harapkan.

#### Masalah performa

Jika pernyataan dieksekusi lambat atau mengalami timeout, tambahkan filter rentang tanggal ke klausa WHERE. Operasi yang memindai seluruh tabel memproses jutaan baris secara tidak perlu:

```sql
-- Lambat: tanpa filter tanggal
SELECT device_id, COUNT(*) FROM processed_common_data.trips GROUP BY device_id;

-- Cepat: filter rentang tanggal
SELECT device_id, COUNT(*) 
FROM processed_common_data.perjalanan 
WHERE trip_start_time >= CURRENT_DATE - INTERVAL '30 days'
Kelompokkan berdasarkan device_id;
```

Untuk panduan performa tambahan, lihat [Cara mengakses skema IoT Query](#how-to-access-iot-query-schemas) untuk praktik terbaik dalam penyaringan dan pemilihan skema.

### Di mana menemukan contoh SQL

Itu [Buku resep SQL](/docs/analytics/id/example-queries.md) menyediakan contoh lengkap untuk analisis telematika umum. Resep-resep ini menunjukkan pola untuk analisis perjalanan, perhitungan kunjungan zona, deteksi idle, dan metrik Armada. Setiap resep mencakup pernyataan SQL lengkap, penjelasan logika, dan hasil sampel.

Sesuaikan contoh Recipe Book untuk visualisasi dengan mengubah klausa SELECT agar sesuai dengan kebutuhan visualisasi. Resep yang menghasilkan catatan perjalanan terperinci dapat menjadi diagram batang dengan menambahkan agregasi GROUP BY dan COUNT. Pernyataan yang menghitung metrik per kendaraan dapat menjadi ubin statistik dengan menambahkan SUM di seluruh Kendaraan.

Anda hanya perlu:

1. Salin contoh dari [Buku resep](/docs/analytics/id/example-queries.md) ke Editor Dashboard Studio.
2. Uji dengan data aktual Anda.
3. Verifikasi hasilnya, lalu ubah klausa SELECT untuk visualisasi target Anda.

Logika inti WHERE dan JOIN tetap sama; Anda hanya menyesuaikan struktur keluaran.

Untuk detail skema, lihat [Ikhtisar skema IoT Query](/docs/analytics/id/iot-query/schema-overview.md). Referensi ini menjelaskan tabel yang tersedia, definisi kolom, dan hubungan antara lapisan Raw data, Transformation, dan 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/id/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.
