Via Kondado: Referência KSQL

O KSQL é a linguagem de consulta da Kondado. Ele utiliza uma sintaxe em formato JSON que permite filtrar, agrupar, ordenar e transformar seus dados de forma simples e segura.

ℹ️ Beta: Consultas via KSQL estão disponíveis em modo beta.

Estrutura básica

Uma consulta KSQL é enviada como um objeto JSON dentro da chave ksql. Os campos disponíveis são:

CampoObrigatórioDescrição
table_nameSimNome da tabela a ser consultada
columnsSimLista de colunas a retornar
column_aggregationsNãoTipo de agregação para cada coluna (ex: "sum", "avg", "none")
dimensionsNãoColunas de agrupamento (equivalente ao GROUP BY)
where_conditionsNãoCondições de filtro
order_byNãoOrdenação dos resultados
limitNãoNúmero máximo de registros (máximo: 1.000)
customColumnsNãoColunas calculadas com expressões personalizadas
column_transformationsNãoTransformações aplicadas às colunas
joinsNãoJunção com outras tabelas
unionNãoArray de consultas para combinar com UNION ALL (substitui os demais campos)
withNãoArray de CTEs (Common Table Expressions) — subconsultas nomeadas reutilizáveis (veja seção abaixo)

Exemplo mínimo

{
  "ksql": {
    "table_name": "vendas",
    "columns": ["produto", "valor", "data"]
  }
}

Filtros (where_conditions)

Os filtros são definidos como uma lista de condições. Todas as condições são combinadas com E (AND).

"where_conditions": [
  {"column": "status", "operator": "=", "value": "ativo"},
  {"column": "valor", "operator": ">", "value": 100}
]

Comparação coluna-com-coluna (value_column)

Em vez de comparar uma coluna com um valor fixo, você pode comparar uma coluna com outra coluna usando value_column no lugar de value:

"where_conditions": [
  {"column": "receita", "operator": ">", "value_column": "custo"},
  {"column": "data_envio", "operator": "<=", "value_column": "data_limite"}
]

value_column aceita apenas nomes de colunas válidos (letras, números, _ e .). As mesmas regras de segurança de column se aplicam.

Operadores de comparação

OperadorDescriçãoExemplo de valor
=Igual a"ativo"
!=Diferente de"cancelado"
>Maior que100
<Menor que50
>=Maior ou igual a100
<=Menor ou igual a200

Operadores de conjunto

OperadorDescriçãoExemplo de valor
INEstá na lista["SP", "RJ", "MG"]
NOT INNão está na lista["cancelado", "expirado"]

Operadores de texto

OperadorDescriçãoExemplo de valor
LIKECorresponde ao padrão (use % como coringa)"%kondado%"
NOT LIKENão corresponde ao padrão"%teste%"
STARTS_WITHComeça com"BR"
ENDS_WITHTermina com".com"
CONTAINSContém o texto"kondado"
NOT_CONTAINSNão contém o texto"teste"

Operadores de nulo

OperadorDescrição
IS NULLÉ nulo
IS NOT NULLNão é nulo

Operador de intervalo

OperadorDescriçãoExemplo de valor
BETWEENEstá entre dois valores[100, 500]

Operadores de data relativa

Estes operadores facilitam filtros de data sem precisar calcular datas manualmente:

OperadorDescrição
LAST_N_DAYSÚltimos N dias
NEXT_N_DAYSPróximos N dias
LAST_N_HOURSÚltimas N horas
LAST_N_MINUTESÚltimos N minutos
THIS_WEEKSemana atual
LAST_WEEKSemana passada
THIS_MONTHMês atual
LAST_MONTHMês passado
THIS_QUARTERTrimestre atual
LAST_QUARTERTrimestre passado
THIS_YEARAno atual
LAST_YEARAno passado

Exemplo:

{"column": "criado_em", "operator": "LAST_N_DAYS", "value": 7}

Agregações

Para calcular métricas sobre seus dados, use column_aggregations junto com dimensions.

O campo column_aggregations é uma lista com o mesmo tamanho de columns. Cada posição define a agregação da coluna correspondente. Use "none" para colunas sem agregação (que devem estar em dimensions).

{
  "ksql": {
    "table_name": "pedidos",
    "columns": ["categoria", "receita", "quantidade"],
    "column_aggregations": ["none", "sum", "count"],
    "dimensions": ["categoria"]
  }
}

Funções de agregação disponíveis

FunçãoDescrição
noneSem agregação (coluna de agrupamento)
sumSoma dos valores
avgMédia dos valores
countContagem de registros
count_distinctContagem de valores únicos
minValor mínimo
maxValor máximo
stddevDesvio padrão
varianceVariância

Ordenação (order_by)

"order_by": [
  {"column": "receita", "direction": "desc"},
  {"column": "nome", "direction": "asc"}
]

Colunas calculadas (customColumns)

Crie colunas derivadas usando expressões:

"customColumns": [
  {"name": "lucro", "expression": "receita - custo"},
  {"name": "margem", "expression": "(receita - custo) / receita * 100"}
]

As colunas calculadas podem ser usadas em columns, where_conditions, order_by e dimensions, como qualquer outra coluna.

Funções disponíveis em expressões

Matemáticas: ABS, CEIL, FLOOR, ROUND, TRUNCATE, MOD, SQRT, POWER, EXP, LOG, LN, SIGN

Texto: UPPER, LOWER, TRIM, LTRIM, RTRIM, SUBSTR, SUBSTRING, LENGTH, REPLACE, CONCAT, SPLIT_PART, LEFT, RIGHT, LPAD, RPAD, REVERSE, REPEAT, INSTR, LOCATE, REGEXP_EXTRACT, REGEXP_REPLACE, REGEXP_LIKE

Data: DATE, YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, DATE_FORMAT, DATE_TRUNC, DATE_ADD, DATE_DIFF, CURRENT_DATE, CURRENT_TIMESTAMP, NOW, EXTRACT, TO_DATE, TO_TIMESTAMP, FROM_UNIXTIME

Conversão: CAST, COALESCE, NULLIF, NVL, IFNULL, GREATEST, LEAST

Condicional: IF, IIF, CASE WHEN ... THEN ... ELSE ... END

Transformações de colunas (column_transformations)

Aplique transformações sequenciais a colunas existentes. As transformações são processadas na ordem em que aparecem.

"column_transformations": {
  "nome": [
    {"type": "text", "operation": "uppercase"}
  ],
  "criado_em": [
    {"type": "date", "operation": "year_month"}
  ],
  "valor": [
    {"type": "number", "operation": "round", "params": {"decimals": 2}}
  ]
}

Transformações de texto: uppercase, lowercase, trim, ltrim, rtrim, extract_domain, extract_before, extract_after, replace (params: find, replace), regexp_extract (params: pattern), regexp_replace (params: pattern, replacement)

Transformações de data: date, year_month, year_week, year_quarter, year, hour, minute, extract_year, extract_month, extract_day, extract_hour, date_add_days (params: days), date_add_hours (params: hours), date_add_minutes (params: minutes)

Transformações numéricas: round (params: decimals), floor, ceil, abs, truncate (params: decimals), divide (params: divisor), multiply (params: multiplier)

Conversões de tipo: cast_to_text, cast_to_int, cast_to_number, cast_to_date, cast_to_timestamp

JOINs

Combine dados de múltiplas tabelas:

{
  "ksql": {
    "table_name": "pedidos",
    "columns": ["pedidos.id", "clientes.nome", "pedidos.total"],
    "column_aggregations": ["none", "none", "none"],
    "joins": [
    {
      "tableName": "clientes",
      "joinType": "LEFT",
      "conditions": [
        {
          "leftColumn": "pedidos.cliente_id",
          "rightColumn": "clientes.id"
        }
      ]
    }
    ]
  }
}

Tipos de JOIN: INNER (apenas registros com correspondência), LEFT (todos da tabela principal + correspondências), RIGHT (todos da tabela unida + correspondências), FULL (todos de ambas), CROSS (produto cartesiano).

Ao usar JOINs, prefixe os nomes das colunas com o nome da tabela (ex: pedidos.id, clientes.nome).

UNION ALL

Combine resultados de consultas em tabelas diferentes. Todas as consultas ficam dentro do array union (mínimo 2). Os campos order_by e limit ficam no nível raiz.

{
  "ksql": {
    "union": [
      {
        "table_name": "vendas_2025",
      "columns": ["mes", "receita"],
      "column_aggregations": ["none", "sum"],
      "dimensions": ["mes"]
      },
      {
        "table_name": "vendas_2024",
      "columns": ["mes", "receita"],
      "column_aggregations": ["none", "sum"],
      "dimensions": ["mes"]
      }
    ],
    "order_by": [{"column": "receita", "direction": "desc"}],
    "limit": 500
  }
}

CTEs — Common Table Expressions (with)

O parâmetro with permite criar subconsultas nomeadas (CTEs) que podem ser referenciadas na consulta principal como se fossem tabelas. Isso é útil para organizar consultas complexas em etapas.

O with é um array de objetos. Cada objeto define um CTE com:

CampoObrigatórioDescrição
aliasSimNome do CTE (usado como nome de tabela na consulta principal)
ksqlSim*Consulta KSQL que define os dados do CTE
saved_query_idSim*ID de uma consulta salva que será usada como CTE (alternativa ao ksql)

* Use ksql ou saved_query_id, nunca ambos.

CTE com consulta inline

{
  "ksql": {
    "with": [
      {
        "alias": "vendas_recentes",
        "ksql": {
          "table_name": "vendas",
          "columns": ["produto", "receita", "data_venda"],
          "where_conditions": [
            {"column": "data_venda", "operator": "LAST_N_DAYS", "value": 30}
          ]
        }
      }
    ],
    "table_name": "vendas_recentes",
    "columns": ["produto", "receita"],
    "column_aggregations": ["none", "sum"],
    "dimensions": ["produto"],
    "order_by": [{"column": "receita", "direction": "desc"}],
    "limit": 10
  }
}

CTE com consulta salva

Se você possui consultas salvas, pode referenciá-las pelo ID em vez de reescrever o KSQL:

{
  "ksql": {
    "with": [
      {
        "alias": "base_clientes",
        "saved_query_id": 31
      }
    ],
    "table_name": "base_clientes",
    "columns": ["nome", "email", "total_compras"],
    "order_by": [{"column": "total_compras", "direction": "desc"}],
    "limit": 50
  }
}

Múltiplos CTEs

Você pode definir vários CTEs e combiná-los na consulta principal com JOINs:

{
  "ksql": {
    "with": [
      {
        "alias": "receita_produto",
        "ksql": {
          "table_name": "vendas",
          "columns": ["produto_id", "receita"],
          "column_aggregations": ["none", "sum"],
          "dimensions": ["produto_id"]
        }
      },
      {
        "alias": "custo_produto",
        "ksql": {
          "table_name": "custos",
          "columns": ["produto_id", "custo_total"],
          "column_aggregations": ["none", "sum"],
          "dimensions": ["produto_id"]
        }
      }
    ],
    "table_name": "receita_produto",
    "columns": ["receita_produto.produto_id", "receita_produto.receita", "custo_produto.custo_total"],
    "joins": [
      {
        "tableName": "custo_produto",
        "joinType": "LEFT",
        "conditions": [
          {"leftColumn": "receita_produto.produto_id", "rightColumn": "custo_produto.produto_id"}
        ]
      }
    ]
  }
}

CTEs aninhados (recursivos)

Um CTE pode conter seus próprios CTEs internos, permitindo encadeamento de subconsultas:

{
  "ksql": {
    "with": [
      {
        "alias": "resumo",
        "ksql": {
          "with": [
            {
              "alias": "vendas_mes",
              "ksql": {
                "table_name": "vendas",
                "columns": ["categoria", "receita"],
                "column_aggregations": ["none", "sum"],
                "dimensions": ["categoria"],
                "where_conditions": [
                  {"column": "data_venda", "operator": "LAST_MONTH"}
                ]
              }
            }
          ],
          "table_name": "vendas_mes",
          "columns": ["categoria", "receita"],
          "where_conditions": [
            {"column": "receita", "operator": ">", "value": 1000}
          ]
        }
      }
    ],
    "table_name": "resumo",
    "columns": ["categoria", "receita"],
    "order_by": [{"column": "receita", "direction": "desc"}]
  }
}

⚠️ Todos os CTEs são executados no mesmo banco de dados da consulta principal. As mesmas regras de segurança e validação se aplicam a cada CTE individualmente.

Limites e restrições

RestriçãoValor
Máximo de registros por consulta1.000
Condições de filtroApenas AND
SubconsultasSuportadas via CTEs (parâmetro with)
DISTINCTNão suportado (use count_distinct)
UNION simplesNão suportado (apenas UNION ALL)

Exemplos completos

Vendas por região no último mês

{
  "ksql": {
    "table_name": "vendas",
    "columns": ["regiao", "receita", "pedidos"],
  "column_aggregations": ["none", "sum", "count"],
  "dimensions": ["regiao"],
  "where_conditions": [
    {"column": "data_venda", "operator": "LAST_MONTH"}
  ],
  "order_by": [{"column": "receita", "direction": "desc"}]
  }
}

Top 10 clientes por valor de compra

{
  "ksql": {
    "table_name": "pedidos",
    "columns": ["pedidos.cliente_id", "clientes.nome", "pedidos.valor"],
  "column_aggregations": ["none", "none", "sum"],
  "dimensions": ["pedidos.cliente_id", "clientes.nome"],
  "joins": [
    {
      "tableName": "clientes",
      "joinType": "LEFT",
      "conditions": [
        {"leftColumn": "pedidos.cliente_id", "rightColumn": "clientes.id"}
      ]
    }
  ],
  "order_by": [{"column": "valor", "direction": "desc"}],
  "limit": 10
  }
}

Filtro com múltiplas condições

{
  "ksql": {
    "table_name": "leads",
    "columns": ["nome", "email", "origem", "score"],
  "where_conditions": [
    {"column": "score", "operator": ">=", "value": 80},
    {"column": "origem", "operator": "IN", "value": ["google", "facebook"]},
    {"column": "email", "operator": "IS NOT NULL"},
    {"column": "criado_em", "operator": "LAST_N_DAYS", "value": 90}
  ],
  "order_by": [{"column": "score", "direction": "desc"}],
  "limit": 100
  }
}

Consultas KSQL estão em modo beta

Escrito por·Publicado em 2026-04-01·Atualizado em 2026-04-23