すべてのプロダクト
Search
ドキュメントセンター

Hologres:増分更新でサポートされる関数

最終更新日:Jun 05, 2026

動的テーブルの増分更新は、基本的な集約関数 (COUNT、SUM、MIN/MAX、COUNT DISTINCT) に加え、このトピックに記載されている拡張関数もサポートしています。

関数のサポート一覧

関数 説明 サポート対象バージョン
ROW_NUMBER / RANK TopN 処理用のウィンドウ関数です。パーティション内で行に順位を付け、上位 N 件のレコードをフィルタリングします。サポートされるのは ROW_NUMBER と RANK のみです。auto_refresh_modeauto に設定すると、自動の増分更新を有効化できます。 V4.2 以降
COUNT, SUM, MIN/MAX, COUNT DISTINCT 基本的な集約関数 すべてのバージョン
hg_id_encoding_int4 / hg_id_encoding_int8 text 型の UID を int32 または int64 にマッピングし、マッピング内容をユーザーマッピングテーブルに自動的に書き込みます。RoaringBitmap と組み合わせて、長期間にわたるユニークビジター (UV) の算出によく使用されます。 V4.1 以降
min_by / max_by ある列の値が最小または最大となる行から、別の列の値を返します。 V4.0 以降
RB_BUILD_AGG int32 または int64 列から RoaringBitmap を構築します。 V3.1 以降
string_agg デリミタを使用して列の値を文字列に連結します。string_agg([distinct]) 構文を使用するには V3.1.10 以降が必要です。 V3.1 以降
array_agg 列の値を配列に集約します。array_agg([distinct]) 構文を使用するには V3.1.10 以降が必要です。 V3.1 以降
any_value GROUP BY クエリにおいて、各グループから非決定的な値を返します。int 型と bytea 型のみサポートします。 V3.1.5 以降

ROW_NUMBER / RANK

Hologres V4.2 以降では、動的テーブルの増分更新で ROW_NUMBER()RANK() のウィンドウ関数がサポートされています。これらの関数を使用して行をパーティション分割して順位付けし、各パーティションから上位 N 件のレコードをフィルタリングできます。これは、リアルタイムな TopN のマテリアライズで一般的なパターンです。

構文

SELECT [column_list]
FROM (
   SELECT [column_list],
     ROW_NUMBER() OVER ([PARTITION BY partition_column[, ...]]
       ORDER BY order_column [ASC|DESC][, ...]) AS rownum
   FROM table_name)
WHERE rownum <= N [AND conditions]

引数:

  • PARTITION BY partition_column:任意。順位付けの前に、行をパーティションにグループ化します。

  • ORDER BY order_column [ASC|DESC]:必須。各パーティション内の順位付けの順序を定義します。

  • rownum <= N:必須。各パーティションから上位 N 行のみを保持します。

注意事項

  • Hologres V4.2 以降でサポートされています。

  • サポートされるのは ROW_NUMBER()RANK() のみです。DENSE_RANKLAGLEAD など、その他のウィンドウ関数はサポートされていません。

  • auto_refresh_modeauto に設定すると、Hologres は動的テーブルの増分モードを自動的に導出します。

次の例では、商品ごとに注文金額の上位 3 件を維持し、5 分ごとに増分更新される動的テーブルを作成します。

-- ソーステーブルを作成します
CREATE TABLE orders (
  order_id   bigint,
  product_id bigint,
  amount     bigint
);

INSERT INTO orders
SELECT i, i % 100, (random() * 1000000)::bigint
FROM generate_series(1, 10000) i;

-- TopN 用の動的テーブルを作成します
CREATE DYNAMIC TABLE top3_orders
WITH (
  freshness = '5 minutes',
  auto_refresh_mode = 'incremental'
) AS
SELECT order_id, product_id, amount
FROM (
   SELECT order_id, product_id, amount,
     ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY amount DESC) AS rownum
   FROM orders)
WHERE rownum <= 3;

-- 特定の商品に対する結果をクエリします
SELECT * FROM top3_orders WHERE product_id = 1;

hg_id_encoding_int4 / hg_id_encoding_int8

hg_id_encoding_int4hg_id_encoding_int8 は、text 型の UID 列を int32 または int64 にマッピングし、マッピング内容をユーザーマッピングテーブルに自動的に書き込みます。これらの関数を動的テーブルの増分更新および RoaringBitmap と組み合わせて使用することで、長期間にわたる UV を算出できます。

エンドツーエンドの例については、「Hologres 動的テーブルを使用して任意の長期間の UV を算出する」をご参照ください。

構文

hg_id_encoding_int4(<user_id>, '<mapping_tablename>')
hg_id_encoding_int8(<user_id>, '<mapping_tablename>')

引数

引数 説明
user_id text マッピング対象の UID 列です。NULL 値はサポートされません。NULL を渡すとエラーが発生します。
mapping_tablename text ユーザーマッピングテーブルの名前です。関数を呼び出す前に、このテーブルを作成してください。

動作

新しい UID から整数へのマッピングをユーザーマッピングテーブルに書き込みます。UID がすでにテーブルに存在する場合は既存のマッピングが保持され、重複レコードは挿入されません。

注意事項

  • Hologres V4.1 以降でサポートされています。

  • ユーザーマッピングテーブルには、プライマリキーと、(プライマリキー以外に) ちょうど 1 つの Serial フィールドが必要です。

  • text 型の単一列プライマリキーのみをサポートします。

-- ソーステーブルを作成します
CREATE TABLE base_table(user_id text);
INSERT INTO base_table VALUES('a');

-- ユーザーマッピングテーブルを作成します
CREATE TABLE uid_mapping(user_id text PRIMARY KEY, id serial);

-- UID を整数にマッピングし、uid_mapping に書き込みます
SELECT user_id, hg_id_encoding_int4(user_id, 'uid_mapping') AS res
FROM base_table;

-- マッピングテーブルをクエリして確認します
-- user_id | id
-- --------+----
--   a     |  1

min_by / max_by

min_bymax_by は、ある列の値が最小または最大となる行から、別の列の値を返します。

構文

min_by(expr1, expr2)
max_by(expr1, expr2)

引数

引数 説明
expr2 比較に使用する列です (最小値または最大値を特定します)。
expr1 この列の値が、一致した行から返されます。

戻り値

expr2 が最小 (min_by) または最大 (max_by) となる行の expr1 の値です。

注意事項

Hologres V4.0 以降でサポートされています。

次の例では、イベントのタイムスタンプに基づいて、各ユーザーの最初と最後のイベントを追跡する動的テーブルを作成します。

-- ソーステーブルを作成します
DROP TABLE IF EXISTS detail;
CREATE TABLE detail (
  userid       text,
  event_id     text,
  create_time  timestamptz
);

INSERT INTO detail(userid, event_id, create_time) VALUES
  ('user_1', 'e1', '2024-12-20 10:00:00+08'),
  ('user_1', 'e2', '2024-12-20 11:30:00+08'),
  ('user_1', 'e3', '2024-12-21 09:15:00+08'),
  ('user_2', 'e4', '2024-12-20 08:05:00+08'),
  ('user_2', 'e5', '2024-12-22 14:20:00+08'),
  ('user_3', 'e6', '2024-12-21 16:45:00+08');

-- 動的テーブルを作成します
DROP TABLE IF EXISTS detail_user_first_last_event;

CREATE DYNAMIC TABLE detail_user_first_last_event
WITH (
  auto_refresh_mode = 'incremental',
  computing_resource = 'local',
  freshness = '3 minutes'
)
AS
SELECT
  userid,
  min_by(event_id, create_time) AS first_event_id,
  max_by(event_id, create_time) AS last_event_id,
  date_trunc('day', max(create_time))::date AS dt
FROM detail
GROUP BY userid;

string_agg

string_agg は、列の NULL 以外の値を、固定のデリミタで区切って 1 つの文字列に連結します。

構文

string_agg([distinct] column_expr, const_expr)

引数

引数 説明
column_expr text、char、または varchar 集約対象の列です。
const_expr text 定数 連結した値の間に挿入されるデリミタです。

注意事項

  • ORDER BY 句はサポートされていません。

  • string_agg([distinct]) 構文を使用するには Hologres V3.1.10 以降が必要です。

  • 基本の string_agg は Hologres V3.1 以降でサポートされています。

CREATE DYNAMIC TABLE string_agg_test_dt
  WITH (
    freshness = '3 minutes',
    refresh_mode = 'incremental')
  AS
  SELECT day,
         string_agg(gameversion, ',') AS gameversion_list
    FROM base_table GROUP BY day;

array_agg

array_agg は、列の NULL 以外の値を配列に収集します。

構文

array_agg([distinct] expr)

引数

引数 説明
expr boolean、任意の数値型、text、または bytea 配列に集約する列です。

注意事項

  • ORDER BY 句はサポートされていません。

  • array_agg([distinct]) 構文を使用するには Hologres V3.1.10 以降が必要です。

  • 基本の array_agg は Hologres V3.1 以降でサポートされています。

CREATE DYNAMIC TABLE array_agg_test_dt
  WITH (
    freshness = '3 minutes',
    refresh_mode = 'incremental')
  AS
  SELECT day,
         array_agg(gameversion) AS gameversion_list
    FROM base_table GROUP BY day;

any_value

GROUP BY クエリにおいて、any_value は各集約グループから非決定的な値を返します。

構文

any_value(expr)

引数

引数 説明
expr int または bytea 値が返される列です。

注意事項

  • Hologres V3.1.5 以降でサポートされています。

  • expr には、int 型と bytea 型のみ指定できます。

  • 戻り値は非決定的です。

CREATE DYNAMIC TABLE dt_t0
WITH (
  freshness = '1 minutes',
  auto_refresh_mode = 'auto'
)
AS
SELECT a, any_value(c), sum(b) FROM t0 GROUP BY a;

次のステップ