finder_funnel calculates funnel conversion results within a time window and supports associating events by a shared property value — for example, ensuring that step-by-step conversion is tracked per city or per country rather than just per user ID. Funnel results cannot be grouped by time.
Prerequisites
Before you begin, ensure that you have:
Hologres V2.2.32 or later, or Hologres V3.0.12 or later
Superuser access to install the required extension
Usage notes
Install the flow_analysis extension as a superuser before running finder_funnel:
CREATE extension flow_analysis; -- Install the extension.The extension is installed at the database level. Install it only once per database.
The extension loads into the
publicschema by default and cannot be loaded into other schemas.
Syntax
finder_funnel(
<window>,
<start_timestamp>,
<step_interval>,
<step_numbers>,
<num_events>,
<attr_related>,
<time_zone>,
<is_relative_window>,
<server_timestamp>,
<client_timestamp>,
[<prop1>, <prop2>, ...]
<check_event1>, <check_event2>, ...
)Parameters
All parameters are required.
| Parameter | Description |
|---|---|
<window> | The analysis time window. Unit: milliseconds. |
<start_timestamp> | The start time of the analysis. Accepts TIMESTAMP and TIMESTAMPTZ types. |
<step_interval> | The granularity of each step for conversion calculation. Unit: seconds. For example, step_interval=86400 means each step is one day. |
<step_numbers> | The number of steps to analyze. For example, step_interval=86400, step_numbers=7 analyzes funnel data across seven days starting from start_timestamp. |
<num_events> | The number of events to analyze. |
<attr_related> | An INT value that specifies which events have associated properties. Its binary representation determines the association: if bit i is 1, then event i+1 has an associated property. The number of <prop> expressions must equal the number of 1 bits. Set to 0 if no events have associated properties. See How attr_related works. |
<time_zone> | The time zone for the input timestamps. Must be a standard time zone string such as Asia/Shanghai. Only takes effect when is_relative_window is true. |
<is_relative_window> | Specifies whether to use a calendar day window. Default: false. See Calendar day window. |
<server_timestamp> | The server-side time when the event occurred. Accepts TIMESTAMP and TIMESTAMPTZ. Used to assign events to the correct step. |
<client_timestamp> | The client-side time when the event occurred. Accepts TIMESTAMP and TIMESTAMPTZ. Must be the same type as start_timestamp. Used to sort events. |
<prop> | The event property to use for association. All <prop> expressions must return the same data type. Required only when attr_related is non-zero. |
<check_event> | Boolean expressions that identify each event. Events matching these conditions within the <window> duration participate in conversion analysis. For example: event = 'E0001', event = 'E0002', event = 'E0003'. |
How attr_related works
attr_related uses a binary bitmask to specify which events have associated properties.
For example, with four events (E1, E2, E3, E4):
attr_related value | Binary | Events with associated properties |
|---|---|---|
0 | 0000 | None — no property association |
3 | 0011 | E1 and E2 have associated properties |
5 | 0101 | E1 and E3 have associated properties |
15 | 1111 | All four events have associated properties |
When attr_related=3 (binary 11), events E1 and E2 are associated by property. Provide two <prop> expressions — one for each event. E3 and E4 are not associated, so no <prop> expressions are needed for them.
Calendar day window
When is_relative_window=true, the window is split into calendar days (00:00:00 to 23:59:59 each day).
When is_relative_window=true, the following constraints apply:<window>must be an integer multiple of86,400,000(milliseconds per day).
<step_interval>must be86400(one step = one day).
The first calendar day starts from the event time and ends at 23:59:59 of the same day. Each subsequent day is a full calendar day. Use this mode to observe daily funnel data for refined operations analysis.
Return value
finder_funnel returns one row per user in the format:
{<highest event reached>, <event reached in step 1>, <event reached in step 2>, ...}The first number is the highest-numbered event the user reached across all steps.
Each subsequent number is the highest-numbered event reached within that step.
For example, {4, 4, 3, 2} means the user ultimately reached event 4. In step 1, they reached event 4; in step 2, event 3; in step 3, event 2.
funnel_rep
Use funnel_rep to aggregate finder_funnel results across all users. For details, see Dimension grouping funnel function (finder_group_funnel).
Examples
The following examples use this sample dataset:
CREATE TABLE finder_funnel_test_1(id INT, event_time TIMESTAMP, event TEXT, province TEXT, city TEXT);
INSERT INTO finder_funnel_test_1 VALUES
(1111, '2024-01-02 00:00:00', 'Registration', 'Beijing', 'Beijing'),
(1111, '2024-01-02 00:00:01', 'Logon', 'Beijing', 'Beijing'),
(1111, '2024-01-02 00:00:02', 'Payment', 'Beijing', 'Beijing'),
(1111, '2024-01-02 00:00:03', 'Exit', 'Beijing', 'Beijing'),
(1111, '2024-01-03 00:00:00', 'Registration', 'Beijing', 'Beijing'),
(1111, '2024-01-03 00:00:01', 'Logon', 'Beijing', 'Beijing'),
(1111, '2024-01-03 00:00:02', 'Payment', 'Beijing', 'Beijing'),
(1111, '2024-01-04 00:00:00', 'Registration', 'Beijing', 'Beijing'),
(1111, '2024-01-04 00:00:01', 'Logon', 'Beijing', 'Beijing'),
(2222, '2024-01-02 00:00:00', 'Registration', 'Zhejiang', 'Hangzhou'),
(2222, '2024-01-02 00:00:00', 'Logon', 'Zhejiang', 'Hangzhou'),
(2222, '2024-01-02 00:00:01', 'Payment', 'Zhejiang', 'Hangzhou'),
(2222, '2024-01-02 00:00:03', 'Payment', 'Zhejiang', 'Hangzhou');Example 1: Basic funnel without property association
A 3-day window split into 3 daily steps, tracking 4 events, with no property association (attr_related=0):
SELECT
id,
finder_funnel(
86400000 * 3, -- 3-day window
EXTRACT(epoch FROM TIMESTAMP'2024-01-02 00:00:00')::BIGINT,
86400, -- 1-day steps
3, -- 3 steps
4, -- 4 events
0, -- no property association
'Asia/Shanghai',
FALSE,
event_time,
event_time,
event = 'Registration',
event = 'Logon',
event = 'Payment',
event = 'Exit'
) AS funnel_res
FROM
finder_funnel_test_1
GROUP BY
id;Result:
id | funnel_res
------+------------
2222 | {3,3,0,0}
1111 | {4,4,3,2}
(2 rows)id=1111, {4,4,3,2}: User 1111 ultimately reached event 4 (Exit). In step 1 (Jan 2), they reached event 4; in step 2 (Jan 3), event 3 (Payment); in step 3 (Jan 4), event 2 (Logon).id=2222, {3,3,0,0}: User 2222 reached event 3 (Payment) in step 1, with no further progression.
Example 2: Funnel with property association
Set attr_related=3 (binary 11) so that events 1 (Registration) and 2 (Logon) are associated by the province property. Conversion between these events is tracked only when both events share the same province value.
SELECT
id,
finder_funnel(
86400000 * 3,
EXTRACT(epoch FROM TIMESTAMP'2024-01-02 00:00:00')::BIGINT,
86400,
3,
4,
3, -- attr_related=3 (binary 11): events 1 and 2 have associated properties
'Asia/Shanghai',
FALSE,
event_time,
event_time,
province, -- prop for event 1 (Registration)
province, -- prop for event 2 (Logon)
event = 'Registration',
event = 'Logon',
event = 'Payment',
event = 'Exit'
) AS funnel_res
FROM
finder_funnel_test_1
GROUP BY
id;Result:
id | funnel_res
------+------------
2222 | {3,3,0,0}
1111 | {4,4,3,2}
(2 rows)The results show the highest event each user reached — and the highest event per step — after applying the property association constraint.
Example 3: Aggregate results with funnel_rep
Use funnel_rep to sum up the per-user finder_funnel results into a group-level view:
SELECT
funnel_rep(3, 4, funnel_res)
FROM (
SELECT
id,
finder_funnel(
86400000 * 3,
EXTRACT(epoch FROM TIMESTAMP'2024-01-02 00:00:00')::BIGINT,
86400,
3,
4,
3,
'Asia/Shanghai',
FALSE,
event_time,
event_time,
province,
province,
event = 'Registration',
event = 'Logon',
event = 'Payment',
event = 'Exit'
) AS funnel_res
FROM
finder_funnel_test_1
GROUP BY
id
) a;Result:
funnel_rep
-------------------------------------------
{"2,2,2,1","2,2,2,1","1,1,1,0","1,1,0,0"}
(1 row)Example 4: Calendar day window
This example uses a 3-calendar-day window (is_relative_window=TRUE) to observe daily funnel data.
Create the table and insert data:
CREATE TABLE finder_funnel_test_3(id INT, event_time TIMESTAMP, event TEXT, province TEXT, city TEXT); INSERT INTO finder_funnel_test_3 VALUES (1111, '2024-01-02 00:00:02', 'Registration', 'Beijing', 'Beijing'), (1111, '2024-01-02 00:00:03', 'Logon', 'Beijing', 'Beijing'), (1111, '2024-01-03 00:00:04', 'Payment', 'Beijing', 'Beijing'), (1111, '2024-01-05 00:00:01', 'Exit', 'Beijing', 'Beijing'), (2222, '2024-01-02 00:00:00', 'Registration', 'Zhejiang', 'Hangzhou'), (2222, '2024-01-02 00:00:00', 'Logon', 'Zhejiang', 'Hangzhou'), (2222, '2024-01-02 00:00:01', 'Payment', 'Zhejiang', 'Hangzhou'), (2222, '2024-01-02 00:00:03', 'Payment', 'Zhejiang', 'Hangzhou');Run the query with a calendar day window:
SELECT id, finder_funnel( 86400000 * 3, EXTRACT(epoch FROM TIMESTAMP'2024-01-02 00:00:00')::BIGINT, 86400, 3, 4, 0, 'Asia/Shanghai', TRUE, -- calendar day mode event_time, event_time, event = 'Registration', event = 'Logon', event = 'Payment', event = 'Exit' ) AS funnel_res FROM finder_funnel_test_3 GROUP BY id;Result:
id | funnel_res ------+------------ 1111 | {3,3,0,0} 2222 | {3,3,0,0} (2 rows)For
id=1111: the first calendar day runs from2024-01-02 00:00:02to23:59:59. January 3 and January 4 are the second and third calendar days. January 5 falls outside the 3-day window, so the Exit event is not counted — user 1111 reaches event 3 (Payment) as the final result.