mirror of
https://github.com/PostHog/posthog.git
synced 2024-12-01 12:21:02 +01:00
e60e3c7964
* wip: pagination for persons on clickhouse funnels * wip: added offset support for getting a list of persons; added support for conversion window; * fixed mypy exception * helper function to insert data for local testing * moved generate code into separate class for more functionality later * corrected person_distinct_id to use the person id from postgres * minor corrections to generate local class along with addition of data cleanup via destroy() method * reduce the number of persons who make it to each step * moved funnel queries to a new folder for better organization; separated funnel_persons and funnel_trends_persons into individual classes; * funnel persons and tests * initial implementation * invoke the funnel or funnel trends class respectively * add a test * add breakdown handling and first test * add test stubs * remove repeats * mypy corrections and PR feedback * run funnel test suite on new query implementation * remove imports * corrected tests * minor test updates * correct func name * fix types * unordered step and test * func name change * move builder functions to funnel base * add test classe for new funnel * resolve issues with unordered funnel * oops * remove breakdown, fix mypy error * Handle multiple same events in the funnel (#4863) * dedup + tests * deep equality. Tests to come * write test for entity equality * finish testing funnels * clean up comments * from O(2^N) to O(N) * add query intuition blurb * rm todo * wip persons * wip persons 2 * address comments * test things, fix bugs * match result format to funnel.py Co-authored-by: Buddy Williams <buddy@posthog.com> Co-authored-by: eric <eeoneric@gmail.com>
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
from typing import List
|
||
|
||
from ee.clickhouse.queries.funnels.base import ClickhouseFunnelBase
|
||
from ee.clickhouse.sql.funnels.funnel import FUNNEL_SQL
|
||
|
||
|
||
class ClickhouseFunnel(ClickhouseFunnelBase):
|
||
def get_query(self, format_properties):
|
||
return FUNNEL_SQL.format(**format_properties)
|
||
|
||
|
||
class ClickhouseFunnelNew(ClickhouseFunnelBase):
|
||
def get_query(self, format_properties):
|
||
|
||
steps_per_person_query = self.get_step_counts_query()
|
||
max_steps = len(self._filter.entities)
|
||
|
||
return f"""
|
||
SELECT {self._get_count_columns(max_steps)} {self._get_step_time_avgs(max_steps)} FROM (
|
||
{steps_per_person_query}
|
||
) SETTINGS allow_experimental_window_functions = 1
|
||
"""
|
||
|
||
def get_step_counts_query(self):
|
||
steps_per_person_query = self._get_steps_per_person_query()
|
||
max_steps = len(self._filter.entities)
|
||
|
||
return f"""SELECT person_id, max(steps) AS steps {self._get_step_time_avgs(max_steps)} FROM (
|
||
{steps_per_person_query}
|
||
) GROUP BY person_id
|
||
"""
|
||
|
||
def _format_results(self, results):
|
||
# Format of this is [step order, person count (that reached that step), array of person uuids]
|
||
steps = []
|
||
total_people = 0
|
||
|
||
for step in reversed(self._filter.entities):
|
||
|
||
if results[0] and len(results[0]) > 0:
|
||
total_people += results[0][step.order]
|
||
|
||
serialized_result = self._serialize_step(step, total_people, [])
|
||
if step.order > 0:
|
||
serialized_result.update(
|
||
{"average_conversion_time": results[0][step.order + len(self._filter.entities) - 1]}
|
||
)
|
||
else:
|
||
serialized_result.update({"average_conversion_time": None})
|
||
steps.append(serialized_result)
|
||
|
||
return steps[::-1] # reverse
|
||
|
||
# TODO: include in the inner query to handle breakdown
|
||
def _get_breakdown_prop(self) -> str:
|
||
if self._filter.breakdown:
|
||
return ", prop"
|
||
else:
|
||
return ""
|