![[新機能]Omni上でクエリ結果に対して任意の数値・文字列を1列追加できる「Input Columns」を試してみた](https://images.ctfassets.net/ct0aopd36mqt/4HOwi1sdtoRa4Uys2beuNd/053dbbbb2c9ef51b8ada98776c3e29bf/Omni.png?w=3840&fm=webp)
[新機能]Omni上でクエリ結果に対して任意の数値・文字列を1列追加できる「Input Columns」を試してみた
さがらです。
Omniの新機能として、Input Columns(Beta)がリリースされています。クエリ結果に編集可能な列を直接追加し、データパイプラインを変更せずにインラインで行への注釈付け・データ拡張ができる機能です。
これまでは、集計結果に対して「この行にコメントを付けたい」「一時的にフラグを立てたい」といったニーズがあっても、別途スプレッドシートに書き出すなど、Omniの外で作業せざるを得ませんでした。Input Columnsを使うことで、Omniのクエリ結果画面上でそのまま注釈や評価値を入力・保存できるようになります。実際にどこまでできるか試してみたので、手順と確認結果をまとめます。
機能概要
Input Columnsは、Omniのクエリ結果に対して編集可能な列を追加できる機能です。入力された値は接続先データベースのスクラッチスキーマにテーブルとして書き込まれ、クエリ結果に自動的に結合(JOIN)されます。データベース本体のテーブルを直接変更するわけではなく、別テーブルとして値を持たせる仕組みです。
想定されている利用シーンとしては、以下のようなものが公式Docに挙げられています。
- チケットやオーダーのトリアージ・レビューワークフロー
- リード品質評価などの定性的スコアリング
- 分析チームによる協調的な注釈付け
- データ異常値の追跡
- 売上予測に対する人的な調整
制限事項
- 2026年7月3日時点ではBeta機能です。GAまでに仕様が変わる可能性があります
- Input Columnsはワークブック単位のスコープに限定され、共有モデル層(Shared model)に昇格させることはできません
- 列作成後は、データ型(Text / Number)とKey Columnsの変更ができません。変更したい場合は列を削除して作り直す必要があります
- 列を削除すると、その列に入力されていた値もすべて完全に削除されます。取り消しはできません
- サポートされているデータ型はTextとNumberのみです
前提条件
- 検証環境: 接続先はSnowflake
- 必要な権限: 対象の接続に対して
Restricted Querier・Querier・Connection Adminのいずれかのロールを保有していること - 依存する設定:
- 接続にスクラッチスキーマ(scratch schema)が設定されていること。
- この設定は、接続のセットアップガイド(Snowflakeの場合は
Schema for Table Uploads欄)に該当するものと思われます。両者とも「テーブルアップロード用に専用スキーマを用意し、他のモデリング用テーブルとは共存させない」「これによってdatabase writebacksが有効になる」という説明が共通しているため、実質的に同じ設定を指していると考えられます
- この設定は、接続のセットアップガイド(Snowflakeの場合は
- 組織設定(
Settings > Content permissionsのDefault document abilities)でUpload dataが有効化されていること(組織側の設定にはOrganization Admin権限が必要です) - 対象ドキュメントの設定(Document settings)でも
Upload dataが有効化されていること - データアップロードを許可するモデルロールがユーザーに割り当てられていること
- 接続にスクラッチスキーマ(scratch schema)が設定されていること。
権限や設定が1つでも欠けていると、後述のAdd input columnメニュー自体が出てこなかったり、列の作成に失敗したりするので、事前にご確認ください。
事前準備
準備項目A: Schema for Table Uploadsの設定
Input Columnsの前提条件である「スクラッチスキーマ」は、Snowflake接続の設定項目でいうSchema for Table Uploadsに該当するものと思われます。未設定の場合は、以下の手順で設定します。
まず、Snowflake側にテーブルアップロード専用のスキーマを作成します。このスキーマは、他のモデリング用テーブルと共存させることができない点にご注意ください。
Snowflakeでのスキーマ作成・権限付与SQL(クリックで展開)
-- テーブルアップロード専用スキーマの作成
CREATE SCHEMA IF NOT EXISTS <upload_database>.<csv_schema>;
-- Omni接続用ロールへの権限付与
GRANT USAGE ON DATABASE <upload_database> TO ROLE omni_role;
GRANT USAGE, CREATE TABLE ON SCHEMA <upload_database>.<csv_schema> TO ROLE omni_role;
スキーマ作成後、Omni側の接続設定画面(Connection settings)を開き、Schema for Table Uploads欄に、先ほど作成したスキーマ名をドット表記(<DATABASE>.<SCHEMA>)で入力して保存します。

準備項目B: Upload dataの有効化確認
今回は、組織設定(Settings > Content permissionsのDefault document abilities)とドキュメント設定の両方で、すでにUpload dataが有効化済みの環境で検証します。

準備項目C: 検証用Topicの確認
検証には、以下のomni_dbt_dwh__fact_order_lifecycleTopicを使います。注文ライフサイクルのファクトテーブルと店舗ディメンションを結合したTopicで、店舗別の遅延件数を確認できるsample queryもすでに定義済みです。
検証用Topic定義(クリックで展開)
base_view: omni_dbt_dwh__fact_order_lifecycle
label: 売上・遅延分析(Tableauデータソース:売上・遅延確認用)
group_label: 売上遅延分析
description: |-
Tableauワークブック「OmniへのClaudeCodeでの変換検証_202603」の
データソース「売上・遅延確認用」を移行したトピック。
注文ライフサイクルデータと店舗情報を結合し、
売上メトリクス(Total Amount / Shipping Fee / GMV)の分析、
配送SLA遵守率の監視、店舗別遅延状況の把握を行う。
default_filters:
omni_dbt_dwh__fact_order_lifecycle.order_datetime:
time_for_duration: [ 180 days ago, 180 days ]
joins:
omni_dbt_dwh__dim_store: {}
ai_context: |-
このトピックは売上・遅延分析用です。注文ライフサイクルファクトテーブルと店舗ディメンションを結合して、
以下の分析が可能です:
- 売上メトリクス(Total Amount, Shipping Fee, GMV)のトレンド分析
- オーダーステータスグループ別の構成比分析
- SLA閾値に基づく配送遅延判定と遅延率の計算
- 店舗別・地域別の遅延状況把握
- 地域別の平均フルフィルメント日数(LODによる固定集計)
パラメータ(フィルター):
- メトリクス切り替え: Total Amount / Shipping Fee / GMV を選択して表示メトリクスを切替
- SLA_閾値: 遅延判定の日数閾値(デフォルト5日)
sample_queries:
店舗別遅延件数:
query:
fields:
[
omni_dbt_dwh__dim_store.store_name,
omni_dbt_dwh__fact_order_lifecycle.delayed_count,
omni_dbt_dwh__fact_order_lifecycle.region_avg_fulfillment_days
]
base_view: omni_dbt_dwh__fact_order_lifecycle
limit: 100
sorts:
- field: omni_dbt_dwh__fact_order_lifecycle.delayed_count
topic: omni_dbt_dwh__fact_order_lifecycle
description: 店舗別の遅延件数と地域平均フルフィルメント日数を表示
prompt: 店舗別の遅延件数を多い順に表示して
月別売上トレンド:
query:
fields:
[
omni_dbt_dwh__fact_order_lifecycle.order_datetime,
omni_dbt_dwh__fact_order_lifecycle.order_status_group,
omni_dbt_dwh__fact_order_lifecycle.selected_metric
]
base_view: omni_dbt_dwh__fact_order_lifecycle
limit: 1000
sorts:
- field: omni_dbt_dwh__fact_order_lifecycle.order_datetime
topic: omni_dbt_dwh__fact_order_lifecycle
description: 月別のオーダーステータスグループ別売上メトリクス推移
prompt: 月別の売上トレンドをステータスグループ別に表示して
Topicのbase_viewであるomni_dbt_dwh__fact_order_lifecycle(注文ライフサイクルファクト)のview定義は以下のとおりです。
omni_dbt_dwh__fact_order_lifecycle view定義(クリックで展開)
# Reference this view as omni_dbt_dwh__fact_order_lifecycle
schema_label: ""
#This description was pulled from dbt.
description: 注文ライフサイクルファクト(累積スナップショット)
schema: omni_dbt_dwh
table_name: FACT_ORDER_LIFECYCLE
dimensions:
order_number:
sql: '"ORDER_NUMBER"'
customer_id:
sql: '"CUSTOMER_ID"'
format: ID
customer_key_current:
sql: '"CUSTOMER_KEY_CURRENT"'
store_key:
sql: '"STORE_KEY"'
order_status:
sql: '"ORDER_STATUS"'
order_date_key:
sql: '"ORDER_DATE_KEY"'
paid_date_key:
sql: '"PAID_DATE_KEY"'
ship_date_key:
sql: '"SHIP_DATE_KEY"'
delivered_date_key:
sql: '"DELIVERED_DATE_KEY"'
order_datetime:
sql: '"ORDER_DATETIME"'
paid_datetime:
sql: '"PAID_DATETIME"'
shipped_datetime:
sql: '"SHIPPED_DATETIME"'
delivered_datetime:
sql: '"DELIVERED_DATETIME"'
cancelled_datetime:
sql: '"CANCELLED_DATETIME"'
days_to_pay:
sql: '"DAYS_TO_PAY"'
days_to_ship:
sql: '"DAYS_TO_SHIP"'
days_to_deliver:
sql: '"DAYS_TO_DELIVER"'
total_fulfillment_days:
sql: '"TOTAL_FULFILLMENT_DAYS"'
total_amount:
sql: '"TOTAL_AMOUNT"'
shipping_fee:
sql: '"SHIPPING_FEE"'
updated_at:
sql: '"UPDATED_AT"'
etl_loaded_at:
sql: '"ETL_LOADED_AT"'
order_lifecycle_key:
sql: '"ORDER_LIFECYCLE_KEY"'
primary_key: true
order_status_group:
sql: |-
CASE ${omni_dbt_dwh__fact_order_lifecycle.order_status}
WHEN '受注' THEN '未処理'
WHEN '支払済' THEN '進行中'
WHEN '出荷済' THEN '進行中'
WHEN '配送完了' THEN '完了'
WHEN 'キャンセル' THEN 'キャンセル'
ELSE 'その他'
END
label: オーダーステータスグループ
sla_judgment:
sql: |-
CASE
WHEN ${omni_dbt_dwh__fact_order_lifecycle.order_status} <> '配送完了'
OR ${omni_dbt_dwh__fact_order_lifecycle.total_fulfillment_days} IS NULL
THEN '未確定'
WHEN ${omni_dbt_dwh__fact_order_lifecycle.total_fulfillment_days} > {{filters.omni_dbt_dwh__fact_order_lifecycle.sla_threshold.value}}
THEN '遅延'
ELSE 'OK'
END
label: SLA判定
region_avg_fulfillment_days:
sql: |-
CASE WHEN ${omni_dbt_dwh__fact_order_lifecycle.order_status} = '配送完了'
THEN ${omni_dbt_dwh__fact_order_lifecycle.total_fulfillment_days} END
label: 地域別_平均フルフィル日数
level_of_detail:
aggregate_type: average
fixed: [ omni_dbt_dwh__dim_store.region ]
measures:
count:
aggregate_type: count
gmv:
sql: SUM(${omni_dbt_dwh__fact_order_lifecycle.total_amount}) +
SUM(${omni_dbt_dwh__fact_order_lifecycle.shipping_fee})
label: GMV
selected_metric:
sql: |-
CASE {{filters.omni_dbt_dwh__fact_order_lifecycle.metric_selector.value}}
WHEN 'Total Amount' THEN SUM(${omni_dbt_dwh__fact_order_lifecycle.total_amount})
WHEN 'Shipping Fee' THEN SUM(${omni_dbt_dwh__fact_order_lifecycle.shipping_fee})
WHEN 'GMV' THEN SUM(${omni_dbt_dwh__fact_order_lifecycle.total_amount}) + SUM(${omni_dbt_dwh__fact_order_lifecycle.shipping_fee})
END
label: 指定メトリクス(パラメータ参照)
delivered_count:
sql: |-
CASE WHEN ${omni_dbt_dwh__fact_order_lifecycle.order_status} = '配送完了'
THEN ${omni_dbt_dwh__fact_order_lifecycle.order_number} END
label: 配送完了件数
aggregate_type: count_distinct
delayed_count:
sql: |-
CASE WHEN ${omni_dbt_dwh__fact_order_lifecycle.sla_judgment} = '遅延'
THEN ${omni_dbt_dwh__fact_order_lifecycle.order_number} END
label: 遅延件数
aggregate_type: count_distinct
delay_rate:
sql: ${omni_dbt_dwh__fact_order_lifecycle.delayed_count} /
NULLIF(${omni_dbt_dwh__fact_order_lifecycle.delivered_count}, 0)
label: 遅延率
filters:
metric_selector:
type: string
label: メトリクス切り替え
suggestion_list:
- value: Total Amount
- value: Shipping Fee
- value: GMV
default_filter:
is: Total Amount
filter_single_select_only: true
sla_threshold:
type: number
label: SLA_閾値
default_filter:
is: 5
#The info below was pulled from your dbt repository and is read-only.
dbt:
name: fact_order_lifecycle
target_schema: INVALID_SCHEMA
description: 注文ライフサイクルファクト(累積スナップショット)
config:
schema: dwh
materialized: incremental
code: |-
-- fact_order_lifecycle.sql
-- 注文ライフサイクルファクト(累積スナップショット)
-- 粒度: 1行=注文
{{ config(
materialized='incremental',
unique_key='order_lifecycle_key',
incremental_strategy='merge',
on_schema_change='append_new_columns'
) }}
with src as (
select
order_number,
customer_id,
store_code,
order_status,
order_datetime,
paid_datetime,
shipped_datetime,
delivered_datetime,
cancelled_datetime,
total_amount,
shipping_fee,
updated_at
from {{ ref('int_order_lifecycle_latest') }}
{% if is_incremental() %}
where updated_at >= dateadd(day, -30, current_timestamp)
{% endif %}
),
dim_join as (
select
s.order_number,
s.customer_id,
c.customer_key as customer_key_current,
st.store_key,
s.order_status,
-- ロールプレイングディメンション(日付キー)
cast(to_char(cast(s.order_datetime as date), 'YYYYMMDD') as integer) as order_date_key,
cast(to_char(cast(s.paid_datetime as date), 'YYYYMMDD') as integer) as paid_date_key,
cast(to_char(cast(s.shipped_datetime as date), 'YYYYMMDD') as integer) as ship_date_key,
cast(to_char(cast(s.delivered_datetime as date), 'YYYYMMDD') as integer) as delivered_date_key,
s.order_datetime,
s.paid_datetime,
s.shipped_datetime,
s.delivered_datetime,
s.cancelled_datetime,
-- リードタイム計算
datediff(day, s.order_datetime, s.paid_datetime) as days_to_pay,
datediff(day, s.paid_datetime, s.shipped_datetime) as days_to_ship,
datediff(day, s.shipped_datetime, s.delivered_datetime) as days_to_deliver,
datediff(day, s.order_datetime, s.delivered_datetime) as total_fulfillment_days,
s.total_amount,
s.shipping_fee,
s.updated_at,
current_timestamp as etl_loaded_at,
{{ dbt_utils.generate_surrogate_key(['s.order_number']) }} as order_lifecycle_key
from src s
left join {{ ref('dim_store') }} st
on s.store_code = st.store_code
left join {{ ref('dim_customer_current') }} c
on s.customer_id = c.customer_id
)
select * from dim_join
結合先のomni_dbt_dwh__dim_store(店舗ディメンション)のview定義は以下のとおりです。
omni_dbt_dwh__dim_store view定義(クリックで展開)
# Reference this view as omni_dbt_dwh__dim_store
schema_label: ""
#This description was pulled from dbt.
description: 店舗ディメンション
schema: omni_dbt_dwh
table_name: DIM_STORE
dimensions:
store_key:
sql: '"STORE_KEY"'
primary_key: true
store_code:
sql: '"STORE_CODE"'
store_name:
sql: '"STORE_NAME"'
store_type:
sql: '"STORE_TYPE"'
region:
sql: '"REGION"'
prefecture:
sql: '"PREFECTURE"'
city:
sql: '"CITY"'
address:
sql: '"ADDRESS"'
open_date:
sql: '"OPEN_DATE"'
close_date:
sql: '"CLOSE_DATE"'
manager_name:
sql: '"MANAGER_NAME"'
created_at:
sql: '"CREATED_AT"'
updated_at:
sql: '"UPDATED_AT"'
measures:
count:
aggregate_type: count
#The info below was pulled from your dbt repository and is read-only.
dbt:
name: dim_store
target_schema: INVALID_SCHEMA
description: 店舗ディメンション
config:
schema: dwh
materialized: table
code: |-
-- dim_store.sql
-- 店舗ディメンション(Type 1)
{{ config(materialized='table') }}
with source as (
select * from {{ ref('stg_store') }}
),
with_key as (
select
{{ dbt_utils.generate_surrogate_key(['store_code']) }} as store_key,
store_code,
store_name,
store_type,
region,
prefecture,
city,
address,
open_date,
close_date,
manager_name,
created_at,
updated_at
from source
)
select * from with_key
referenced_by: [ fact_sales_line, fact_inventory_daily, fact_order_lifecycle ]
このomni_dbt_dwh__fact_order_lifecycleTopicで「店舗別遅延件数」のsample queryを実行すると、店舗ごとの遅延件数が一覧表示されます。今回は、この結果に対して店舗ごとの対応状況をメモできる列をInput Columnsで追加してみます。

試してみた
1. Input columnの追加
まず、先ほどの「店舗別遅延件数」のクエリ結果画面で、列ヘッダーの鉛筆アイコンをクリックし、Add new input columnを選択します。

表示されたダイアログで、以下のように設定します。
- Input column name:
follow_up_note(英数字のみ利用可能) - Input column data type:
Text - Input column editing:
Editable in draft only(まずはドラフト文書内でのみ編集できる設定にします) - Input column mapping:
store_key(この店舗単位で値を一意に紐付けます)

設定後にCreateをクリックすると、クエリ結果にfollow_up_note列が追加されます。下図のように新しい列が空の状態で表示されればOKです。

2. 値の追加
追加した列は初期状態でロックされているため、列ヘッダーのアイコンをクリックしてロックを解除します。

ロック解除後、遅延件数が多い店舗の行のセルをクリックし、「フォロー済み・店長へ確認依頼中」のように対応メモを入力してみます。入力後にEnterキーを押すと次の行に移動できるので、複数店舗分まとめて入力できました。
入力が終わったらSaveをクリックします。保存が完了すると、値がスクラッチスキーマ上のテーブルに書き込まれます。

また、追加したInput columnはフィールドピッカーにも追加されています。

一度画面を離れてクエリを再実行しても、入力した対応メモがそのまま保持されていればOKです。実際に店舗名と遅延件数と追加したInput columnだけを選択してクエリを実行しても、下図のように問題なく表示されました。

ちなみに、Snowflakeのスキーマを見ると、下図のようにテーブルが追加されていました。

3. Editable when publishedへの変更を試す
続けて、Editable in draft onlyで作成した列を、公開済みダッシュボードのエンドユーザーも入力できるEditable when publishedモードに変更できるか試してみます。
列ヘッダーからEdit input columnを選択し、Edit modeをEditable when publishedに変更します。(また、列作成後にInput column nameやInput column mappingを変更しようとすると、変更できませんでした。ドキュメントの記載どおり、これらは列を削除して作り直す以外に変更手段がないようです。)


変更後、このクエリをダッシュボードに配置して公開すると、ダッシュボードを閲覧しているユーザーもfollow_up_note列に直接入力できる状態になりました。エンドユーザー自身にステータス入力してもらうような運用を組みたい場合は、この設定が使えそうです。

最後に
OmniのInput Columnsを試して、クエリ結果に対して直接注釈やステータスを入力・保存できることを確認できました。今回試した「店舗別遅延件数への対応メモ追加」のように、集計結果を見ながらそのままアクションを記録できるのは便利で、遅延対応のトリアージのような定性的な運用ワークフローと相性が良さそうです。







