Files
cfw-autumn/server/tinybird/pipes/aggregate_groupable.pipe
2026-03-27 13:03:20 +00:00

82 lines
3.4 KiB
Plaintext

DESCRIPTION >
Aggregate queries with grouping by a property key, customer_id, or entity_id.
Uses PER-BIN TOP N groups + "AUTUMN_RESERVED" bucket ((N+1) max total per bin).
N is controlled by the max_groups parameter (default 9).
Each time bin shows its own top N groups, not global top N.
Returns unpivoted data: (period, event_name, group_value, total_value, _truncated)
_truncated is true only if at least one bin has more than max_groups unique values.
Frontend maps "AUTUMN_RESERVED" to "Other values" for display.
Parameters:
- group_column: 'customer_id' to group by customer, 'entity_id' to group by entity, 'property' (default) to group by property_key
- max_groups: maximum number of distinct groups to show per bin (default 9, remainder bucketed into AUTUMN_RESERVED)
TOKEN "aggregate_groupable_read" READ
NODE base
DESCRIPTION >
Aggregate raw data by period, event_name, and group_value.
Excludes rows with empty/null group values to prevent irrelevant events
from polluting the top-N and "Other" buckets.
SQL >
%
SELECT
{% if String(bin_size, 'day') == 'hour' %}
formatDateTime(hour, '%F %T') as period,
{% elif String(bin_size, 'day') == 'month' %}
formatDateTime(toStartOfMonth(hour, {{ String(timezone, 'UTC') }}), '%F %T') as period,
{% else %}
formatDateTime(toStartOfDay(hour, {{ String(timezone, 'UTC') }}), '%F %T') as period,
{% end %}
event_name,
{% if String(group_column, 'property') == 'customer_id' %}
customer_id as group_value,
{% elif String(group_column, 'property') == 'entity_id' %}
entity_id as group_value,
{% else %}
{{ column('properties.' + String(property_key, '')) }}::String as group_value,
{% end %}
sum(total_value) as total_value
FROM events_hourly_mv
WHERE
org_id = {{ String(org_id, '') }}
AND env = {{ String(env, 'test') }}
AND event_name IN {{ Array(event_names, 'String', default='[]') }}
AND hour >= toDateTime({{ String(start_date, '2024-01-01 00:00:00') }})
AND hour <= toDateTime({{ String(end_date, '2024-12-31 23:59:59') }})
{% if defined(customer_id) and String(customer_id, '') != '' %}
AND customer_id = {{ String(customer_id) }}
{% end %}
{% if defined(entity_id) and String(entity_id, '') != '' %}
AND entity_id = {{ String(entity_id) }}
{% end %}
{% if String(group_column, 'property') == 'entity_id' %}
AND entity_id IS NOT NULL AND entity_id != ''
{% elif String(group_column, 'property') == 'property' %}
AND {{ column('properties.' + String(property_key, '')) }}::String IS NOT NULL
AND {{ column('properties.' + String(property_key, '')) }}::String != ''
{% end %}
GROUP BY period, event_name, group_value
NODE ranked
DESCRIPTION >
Rank groups within each bin by total_value descending.
SQL >
SELECT
*,
row_number() OVER (PARTITION BY period, event_name ORDER BY total_value DESC) as rn
FROM base
NODE endpoint
TYPE endpoint
SQL >
%
SELECT
period,
event_name,
if(rn <= {{ Int32(max_groups, 9) }}, group_value, 'AUTUMN_RESERVED') as group_value,
sum(total_value) as total_value,
max(rn) > {{ Int32(max_groups, 9) }} as _truncated
FROM ranked
GROUP BY period, event_name, group_value
ORDER BY period, event_name, group_value