Todos os produtos
Search
Central de documentação

Hologres:Funções compatíveis com atualização incremental

Última atualização: Sep 03, 2026

A atualização incremental de Dynamic Table oferece suporte a funções de agregação básicas — COUNT, SUM, MIN/MAX e COUNT DISTINCT — além das funções estendidas listadas neste tópico.

Lista de funções compatíveis

Função

Descrição

Versão compatível

ROW_NUMBER / RANK

Window functions para processamento TopN. Classificam linhas dentro de uma partição e filtram os N principais registros. Apenas ROW_NUMBER e RANK são compatíveis. Defina refresh_mode como auto para ativar a atualização incremental automática.

V4.2 e posterior

LEAD / LAG

Window functions que retornam o valor da linha seguinte ou anterior dentro de uma partição. São comuns no cálculo de deltas entre registros adjacentes, variações entre períodos e transições de estado. Especifique tanto PARTITION BY quanto ORDER BY. Apenas as formas de argumento único lead(expr) e lag(expr) são compatíveis; os argumentos offset e default não são aceitos.

V5.0 e posterior

COUNT, SUM, MIN/MAX, COUNT DISTINCT

Funções de agregação básicas

Todas as versões

hg_id_encoding_int32 / hg_id_encoding_int64

Mapeiam um UID do tipo text para int32 ou int64 e gravam automaticamente o mapeamento em uma tabela de mapeamento de usuário. Ideais para calcular visitantes únicos (UV) em longos períodos com RoaringBitmap.

V4.1 e posterior

min_by / max_by

Retornam o valor de uma coluna da linha com o valor mínimo ou máximo em outra coluna.

V4.0 e posterior

RB_BUILD_AGG

Constrói um RoaringBitmap a partir de uma coluna int32 ou int64.

V3.1 e posterior

string_agg

Concatena valores de coluna em uma string usando um delimitador. A sintaxe string_agg([distinct]) requer V3.1.10 ou posterior.

V3.1 e posterior

array_agg

Agrega valores de coluna em um array. A sintaxe array_agg([distinct]) requer V3.1.10 ou posterior.

V3.1 e posterior

any_value

Em uma consulta GROUP BY, retorna um valor não determinístico de cada grupo. Compatível apenas com os tipos int e binary.

V3.1.5 e posterior

ROW_NUMBER / RANK

O Hologres V4.2 e versões posteriores oferecem suporte às window functions ROW_NUMBER() e RANK() na atualização incremental de Dynamic Table. Use essas funções para particionar e classificar linhas e filtrar os N principais registros de cada partição. Esse é um padrão comum para materialização TopN em tempo real.

Sintaxe

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]

Argumentos:

  • PARTITION BY partition_column: Opcional. Agrupa linhas em partições antes da classificação.

  • ORDER BY order_column [ASC|DESC]: Obrigatório. Define a ordem de classificação dentro de cada partição.

  • rownum <= N: Obrigatório. Mantém apenas as N primeiras linhas de cada partição.

Notas de uso

  • Compatível com Hologres V4.2 e posterior.

  • Defina refresh_mode como auto para permitir que o Hologres derive automaticamente o modo incremental para a Dynamic Table.

Exemplo

O exemplo abaixo cria uma Dynamic Table que mantém os 3 pedidos de maior valor por product, com atualização incremental a cada 5 minutos.

-- Create the source table
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;

-- Create the Dynamic Table for 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;

-- Query results for a specific product
SELECT * FROM top3_orders WHERE product_id = 1;

LEAD / LAG

O Hologres V5.0 e versões posteriores oferecem suporte às window functions lead() e lag() no modo de atualização incremental. Essas funções retornam o valor da linha seguinte ou anterior dentro de uma partição ordenada. Elas são frequentes no cálculo de deltas entre registros adjacentes, variações entre períodos e transições de estado.

Sintaxe

SELECT [column_list],
  {lead | lag}(<expr>) OVER (
    PARTITION BY col1[, col2...]
    ORDER BY col1 [ASC|DESC] [NULLS FIRST|NULLS LAST][, col2 ...]) AS <alias>
FROM table_name;

Parâmetros

  • expr: a coluna a ser lida. Essa coluna também deve aparecer na lista SELECT. Caso contrário, a atualização falhará. Para mais informações, consulte Usage notes.

  • PARTITION BY: obrigatório. As colunas usadas para particionamento. Várias colunas são compatíveis.

  • ORDER BY: obrigatório. As colunas usadas para ordenação. Várias colunas, ASC e DESC, bem como NULLS FIRST e NULLS LAST, são compatíveis.

Notas de uso

  • Compatível com Hologres V5.0 e posterior.

  • Tanto PARTITION BY quanto ORDER BY são obrigatórios.

  • Apenas as formas de argumento único lead(expr) e lag(expr) são compatíveis, o que significa que o offset é sempre 1. As sintaxes lead(expr, offset) e lead(expr, offset, default) não são aceitas.

  • A coluna de entrada de lead ou lag deve constar na lista SELECT. Por exemplo, SELECT id, k, lead(price) OVER (...) falha durante a atualização e deve ser reescrita como SELECT id, k, price, lead(price) OVER (...).

  • As colunas de PARTITION BY e ORDER BY não podem usar tipos de ponto flutuante (float, float4, float8, real ou double precision). Para ordenar por valores decimais, utilize numeric ou decimal. Os tipos de chave compatíveis são int, bigint, smallint, numeric ou decimal, text ou varchar, date, timestamp, timestamptz e bool.

  • Garanta que as colunas ORDER BY sejam únicas dentro de cada partição. Se várias linhas em uma mesma partição compartilharem a mesma chave de ordenação, incluindo múltiplos valores NULL, a atualização incremental resolve o empate por meio de um número de linha interno. Esse comportamento difere da atualização completa e de consultas OLAP regulares, podendo gerar resultados divergentes. Ambos os resultados são válidos sob a semântica SQL. Para garantir determinismo, adicione uma coluna única ao ORDER BY como critério de desempate.

  • IGNORE NULLS e RESPECT NULLS não são compatíveis.

  • A primeira atualização constrói o estado completo e pode levar bastante tempo.

  • A duração de uma atualização incremental depende principalmente da proporção de partições afetadas pela mudança, e não do número de linhas alteradas. O desempenho é melhor quando as alterações se concentram em poucas partições. Se cada alteração abranger todas as partições, prefira a atualização completa. A atualização incremental também mantém uma tabela de estado adicional, cuja sobrecarga de armazenamento é significativamente maior que a da atualização completa. Considere isso no planejamento de capacidade.

Exemplo

O exemplo a seguir calcula a variação de valor entre dois eventos consecutivos para cada usuário.

-- Create the source table for user event details.
CREATE TABLE user_events (
  event_id bigint,
  user_id  text,
  event_ts timestamptz,
  amount   numeric(10,2)
);

INSERT INTO user_events VALUES
  (1, 'u1', '2026-08-20 10:00:00+08', 100.00),
  (2, 'u1', '2026-08-20 11:00:00+08', 150.00),
  (3, 'u1', '2026-08-20 12:00:00+08', 120.00),
  (4, 'u2', '2026-08-20 09:00:00+08', 80.00),
  (5, 'u2', '2026-08-20 10:30:00+08', 95.00);

-- Create the Dynamic Table. The input column amount must appear in the SELECT list.
CREATE DYNAMIC TABLE user_amount_diff
WITH (
  freshness = '5 minutes',
  auto_refresh_mode = 'incremental'
) AS
SELECT
  event_id,
  user_id,
  event_ts,
  amount,
  lag(amount) OVER (PARTITION BY user_id ORDER BY event_ts) AS prev_amount,
  amount - COALESCE(lag(amount) OVER (PARTITION BY user_id ORDER BY event_ts), 0) AS diff
FROM user_events;

SELECT * FROM user_amount_diff ORDER BY user_id, event_ts;

O resultado é apresentado a seguir.

 event_id | user_id |        event_ts        | amount | prev_amount |  diff
----------+---------+------------------------+--------+-------------+--------
        1 | u1      | 2026-08-20 10:00:00+08 | 100.00 |             | 100.00
        2 | u1      | 2026-08-20 11:00:00+08 | 150.00 |      100.00 |  50.00
        3 | u1      | 2026-08-20 12:00:00+08 | 120.00 |      150.00 | -30.00
        4 | u2      | 2026-08-20 09:00:00+08 |  80.00 |             |  80.00
        5 | u2      | 2026-08-20 10:30:00+08 |  95.00 |       80.00 |  15.00
(5 rows)

hg_id_encoding_int32 / hg_id_encoding_int64

As funções hg_id_encoding_int32 e hg_id_encoding_int64 mapeiam uma coluna UID do tipo text para int32 ou int64 e gravam automaticamente o mapeamento em uma tabela de mapeamento de usuário. Use essas funções com a atualização incremental de Dynamic Table e RoaringBitmap para calcular UVs em longos períodos.

Para um exemplo completo de ponta a ponta, consulte Calculating UV over arbitrarily long periods using Hologres Dynamic Tables.

Sintaxe

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

Argumentos

Argumento

Tipo

Descrição

user_id

text

A coluna UID a ser mapeada. Valores NULL não são compatíveis — ocorrerá um erro se NULL for passado.

mapping_tablename

text

O nome da tabela de mapeamento de usuário. Crie esta tabela antes de chamar a função.

Comportamento

Grava novos mapeamentos de UID para inteiro na tabela de mapeamento de usuário. Se um UID já existir na tabela, o mapeamento existente é preservado e nenhuma duplicata é inserida.

Notas de uso

  • Compatível com Hologres V4.1 e posterior.

  • A tabela de mapeamento de usuário deve ter uma chave primária e exatamente um campo Serial (além da chave primária).

  • Apenas chaves primárias de coluna única do tipo text são compatíveis.

Exemplo

-- Create the source table
CREATE TABLE base_table(user_id text);
INSERT INTO base_table VALUES('a');

-- Create the user mapping table
CREATE TABLE uid_mapping(user_id text PRIMARY KEY, id serial);

-- Map UIDs to integers and write mappings to uid_mapping
SELECT user_id, hg_id_encoding_int4(user_id, 'uid_mapping') AS res
FROM base_table;

-- Query the mapping table to verify
-- user_id | id
-- --------+----
--   a     |  1

min_by / max_by

As funções min_by e max_by retornam o valor de uma coluna proveniente da linha com o valor mínimo ou máximo em outra coluna.

Sintaxe

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

Argumentos

Argumento

Descrição

expr2

A coluna usada para comparação (encontra o valor mínimo ou máximo).

expr1

A coluna cujo valor será retornado da linha correspondente.

Retorno

O valor de expr1 da linha onde expr2 atinge seu mínimo (min_by) ou máximo (max_by).

Notas de uso

Compatível com Hologres V4.0 e posterior.

Exemplo

O exemplo a seguir cria uma Dynamic Table que rastreia o primeiro e o último evento de cada usuário, com base nos timestamps dos eventos.

-- Create the source table
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');

-- Create the Dynamic Table
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

A função string_agg concatena valores não nulos de uma coluna em uma única string, separados por um delimitador constante.

Sintaxe

string_agg([distinct] column_expr, const_expr)

Argumentos

Argumento

Tipo

Descrição

column_expr

text, char ou varchar

A coluna a ser agregada.

const_expr

constante text

O delimitador inserido entre os valores concatenados.

Notas de uso

  • A cláusula ORDER BY não é compatível.

  • A sintaxe string_agg([distinct]) exige Hologres V3.1.10 ou posterior.

  • A função básica string_agg está disponível no Hologres V3.1 e posterior.

Exemplo

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

A função array_agg coleta valores não nulos de uma coluna em um array.

Sintaxe

array_agg([distinct] expr)

Argumentos

Argumento

Tipo

Descrição

expr

boolean, qualquer tipo numérico, text ou bytea

A coluna a ser agregada em um array.

Notas de uso

  • A cláusula ORDER BY não é compatível.

  • A sintaxe array_agg([distinct]) exige Hologres V3.1.10 ou posterior.

  • A função básica array_agg está disponível no Hologres V3.1 e posterior.

Exemplo

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

Em uma consulta GROUP BY, a função any_value retorna um valor não determinístico de cada grupo de agregação.

Sintaxe

any_value(expr)

Argumentos

Argumento

Tipo

Descrição

expr

int ou binary

A coluna da qual um valor será retornado.

Notas de uso

  • Compatível com Hologres V3.1.5 e posterior.

  • expr aceita apenas os tipos int e binary.

  • O valor retornado é não determinístico.

Exemplo

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;

Próximos passos