---
title: クエリ（SQL）
description: 蓄積した計測値を任意の SQL で集計し、表示・CSV 出力・グラフ化する
createdAt: 2026-08-17
lastModified: 2026-10-11
sidebar:
  label: クエリ
---

サイドバーの **「データ活用」→「クエリ」** では、蓄積した計測値に対して**任意の SQL**を実行し、結果を表で確認したり CSV に書き出したりできます。定型画面では作れない集計や、月次報告用のデータ抽出に使います。

:::note
SQL の知識が必要な機能です。SQL を書かずに可視化したい場合は[分析](/docs/guides/analytics)や[ダッシュボード](/docs/guides/dashboards)を使ってください。
:::

## クエリを実行する

1. サイドバーの **「データ活用」→「クエリ」** →右上の **「新規クエリ」** をクリックします。サンプル SQL が入った状態でエディタが開きます。

2. SQL を書きます。エディタはシンタックスハイライトとテーブル・列名の補完に対応しています。**「整形」** ボタンで自動整形できます。

3. **「実行」** をクリックすると、下部に結果の表が表示されます。

4. 必要に応じて、上部の入力欄に**クエリ名**を入れて **「保存」** をクリックします。保存したクエリは一覧に並び、ダッシュボードのウィジェットからも参照できます。

**「CSV出力」** をクリックすると、現在の SQL の実行結果を CSV ファイルとしてダウンロードします。

## 使えるテーブル

エディタ横の**テーブル定義パネル**にも表示されます。`metrics` が計測値の本体、`events` が AI アプリのイベント、`dim_*` が名前を引くためのテーブルです。

### `metrics` — 計測値（1 行 = 1 計測）

| 列 | 型 | 内容 |
| --- | --- | --- |
| `ts` | timestamptz | 計測時刻 |
| `tenant_id` | text | 組織 ID（自動でフィルタされます） |
| `site_id` | text | 拠点 ID（現状は `edge_pc_id` と同値） |
| `edge_pc_id` | text | エッジPC ID |
| `device_id` | text | デバイス ID |
| `metric_key` | text | 指標キー |
| `value` | double precision | 計測値 |
| `value_min` / `value_max` / `value_count` | — | 間引き時の最小 / 最大 / 件数。**現状は常に null** |
| `detail` | jsonb | 付随情報。**現状は常に null** |
| `artifact_uri` | text | 成果物 URI（任意） |

### `events` — AI アプリのイベント（1 行 = 1 回の発生）

| 列 | 型 | 内容 |
| --- | --- | --- |
| `id` | text | イベント ID |
| `ts` | timestamptz | 発生時刻 |
| `tenant_id` | text | 組織 ID（自動でフィルタされます） |
| `site_id` / `edge_pc_id` | text | 拠点 ID / エッジPC ID |
| `device_id` | text | AI 推論デバイスの ID |
| `event_type` | text | `presenceStart`（在/不在ルールが「いる」になった）/ `presenceEnd`（「いない」になった）/ `plateRead`（ナンバーを新しく読んだ） |
| `rule_id` | text | 判定ルールの ID（`plateRead` は空） |
| `detail` | jsonb | 在/不在は `ruleName`（ルール名）・`matchedCount`（条件に合った件数）・`detections`（写っていたものの配列）・`photoKey`（残した画像）。`plateRead` は `plate`（番号）・`confidence`（確信度）・`bbox`（プレートの枠）・`sourceDeviceId`（カメラ）・`photoKey` |

`detail` の中身は `detail->>'ruleName'` のように取り出します。30 日間残ります。

```sql
-- 直近 7 日、ルールごと・日ごとに「いる」になった回数
select date_trunc('day', ts) as day, detail->>'ruleName' as rule, count(*) as times
from events
where event_type = 'presenceStart' and ts > now() - interval '7 days'
group by 1, 2
order by 1, 2;
```

### `dim_device` — デバイス

`device_id` / `tenant_id` / `edge_pc_id` / `name`（デバイス名）/ `type` / `sensor_kind` / `deleted_at`

削除したデバイスも、計測値が残っているあいだは行が残ります（`deleted_at` に削除日時が入ります）。デバイスを消した直後でも、その計測値を名前つきで集計・CSV 出力できます。現役のデバイスだけを見たいときは `where d.deleted_at is null` を足してください。

### `dim_edge_pc` — エッジPC

`edge_pc_id` / `tenant_id` / `name`（エッジPC名）/ `deleted_at`

### `dim_metric` — 指標定義

`metric_key` / `display_name`（表示名）/ `unit`（単位）/ `value_type`

## SQL の例

### センサ別の直近 1 時間の平均

```sql
select d.name as device, m.metric_key, count(*), round(avg(m.value)::numeric, 2) as avg
from metrics m
join dim_device d using (device_id)
where m.ts > now() - interval '1 hour'
group by 1, 2
order by 1, 2
```

### エッジPC別・1 時間ごとの推移

```sql
select date_trunc('hour', m.ts) as hour,
       e.name as site,
       round(avg(m.value)::numeric, 2) as avg_value
from metrics m
join dim_edge_pc e using (edge_pc_id)
where m.metric_key = 'weight'
  and m.ts > now() - interval '3 days'
group by 1, 2
order by 1, 2
```

### 単位付きで最新値を並べる

```sql
select distinct on (m.device_id)
       d.name as device, mt.display_name as metric,
       m.value, mt.unit, m.ts
from metrics m
join dim_device d using (device_id)
join dim_metric mt using (metric_key)
order by m.device_id, m.ts desc
```

## 結果をグラフにする

実行結果の上にある **「グラフ設定」** で、結果の列をグラフの軸に割り当てられます。

| 項目 | 内容 |
| --- | --- |
| 種別 | `折れ線` / `棒` |
| X軸 | 横軸にする列（時刻列など） |
| 系列（任意） | 系列に分ける列（デバイス名など）。指定すると、値の列は先頭の 1 つだけを使います |
| 値の列 | 縦軸にする列。**系列を指定しない場合は複数選択でき**、選んだ列がそれぞれ系列になります |

設定するとその場でプレビューされ、クエリと一緒に保存されます。保存したグラフ設定は、ダッシュボードの **SQL結果グラフ** ウィジェットで使われます。→ [ダッシュボード](/docs/guides/dashboards)

## 制限とセキュリティ

| 項目 | 制限 |
| --- | --- |
| 実行できる SQL | **`SELECT` または `WITH` で始まる単一文のみ**。複数文（`;` 区切り）や更新系は実行できません |
| 画面表示 | 最大 **1,000 行**（超過分は切り捨てられ、表示に注記が出ます） |
| CSV 出力 | 最大 **50,000 行** |
| 実行時間 | 15 秒でタイムアウトします |
| データ保持 | 7 日より古い計測値は自動削除されます |
| MCP 経由（`run_query`） | 200 行で打ち切られます |

その他の上限値は[制限値と既定値](/docs/reference/limits)にまとめています。

:::note[他組織のデータは見えません]
SQL をどう書いても**他の組織のデータは返りません**。`tenant_id` の条件は自分で書く必要はありません。
:::

## 保存したクエリの管理

- 一覧画面のカードをクリックすると編集画面が開き、保存済みの SQL が自動実行されてプレビューが表示されます。
- カード右上のゴミ箱アイコンで削除できます。**ダッシュボードから参照されているクエリを削除すると、そのウィジェットは表示できなくなります**。
- 削除した直後に出る通知の **「元に戻す」** ですぐ取り消せます。通知を閉じたあとも、一覧下部の **「ゴミ箱」** に 30 日間残っていて戻せます。30 日を過ぎると自動で完全に削除されます。
- 保存したクエリは組織内で共有されます。

## AI エージェントから使う

MCP 経由でも、同じ制限のもとで `describe_query_schema`（テーブル定義の取得）と `run_query`（実行）が使えます。AI に集計を依頼したいときに便利です。→ [MCP 連携](/docs/mcp)
