From 8d35f092e62f86a54b86b6d82429d07031512605 Mon Sep 17 00:00:00 2001 From: Thomas Lento Date: Thu, 23 May 2024 17:33:42 -0700 Subject: [PATCH] Add conversion metric rendering tests (#1214) Add conversion metric rendering tests We do not have rendering tests for conversion metrics, nor do we have any tests with query-time filters added. This change addresses both of these gaps in our coverage, which will give us more confidence as we move ahead with predicate pushdown. Add snapshots for all engines --- .../test_conversion_metric_rendering.py | 166 ++++++ .../test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../DuckDB/test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ .../Trino/test_conversion_metric__plan0.sql | 391 ++++++++++++++ ...est_conversion_metric__plan0_optimized.sql | 110 ++++ ..._metric_with_categorical_filter__plan0.sql | 415 ++++++++++++++ ...th_categorical_filter__plan0_optimized.sql | 131 +++++ ...ion_metric_with_time_constraint__plan0.sql | 483 +++++++++++++++++ ..._with_time_constraint__plan0_optimized.sql | 114 ++++ ...t_conversion_metric_with_window__plan0.sql | 395 ++++++++++++++ ...on_metric_with_window__plan0_optimized.sql | 114 ++++ ...with_window_and_time_constraint__plan0.sql | 511 ++++++++++++++++++ ...w_and_time_constraint__plan0_optimized.sql | 139 +++++ 71 files changed, 19787 insertions(+) create mode 100644 tests_metricflow/query_rendering/test_conversion_metric_rendering.py create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0.sql create mode 100644 tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql diff --git a/tests_metricflow/query_rendering/test_conversion_metric_rendering.py b/tests_metricflow/query_rendering/test_conversion_metric_rendering.py new file mode 100644 index 0000000000..337e631064 --- /dev/null +++ b/tests_metricflow/query_rendering/test_conversion_metric_rendering.py @@ -0,0 +1,166 @@ +from __future__ import annotations + +import datetime + +import pytest +from _pytest.fixtures import FixtureRequest +from dbt_semantic_interfaces.implementations.filters.where_filter import PydanticWhereFilter +from metricflow_semantics.query.query_parser import MetricFlowQueryParser +from metricflow_semantics.test_helpers.config_helpers import MetricFlowTestConfiguration + +from metricflow.dataflow.builder.dataflow_plan_builder import DataflowPlanBuilder +from metricflow.plan_conversion.dataflow_to_sql import DataflowToSqlQueryPlanConverter +from metricflow.protocols.sql_client import SqlClient +from tests_metricflow.query_rendering.compare_rendered_query import convert_and_check + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test rendering a query against a conversion metric.""" + parsed_query = query_parser.parse_and_validate_query( + metric_names=("visit_buy_conversion_rate",), + group_by_names=("metric_time",), + where_constraint=PydanticWhereFilter( + where_sql_template=("{{ TimeDimension('metric_time', 'day') }} = '2020-01-01'") + ), + ) + dataflow_plan = dataflow_plan_builder.build_plan(parsed_query.query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_node, + ) + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric_with_window( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test rendering a query against a conversion metric with a window.""" + parsed_query = query_parser.parse_and_validate_query( + metric_names=("visit_buy_conversion_rate_7days",), + group_by_names=("metric_time",), + where_constraint=PydanticWhereFilter( + where_sql_template=("{{ TimeDimension('metric_time', 'day') }} = '2020-01-01'") + ), + ) + dataflow_plan = dataflow_plan_builder.build_plan(parsed_query.query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_node, + ) + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric_with_categorical_filter( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test rendering a query against a conversion metric with a categorical filter.""" + parsed_query = query_parser.parse_and_validate_query( + metric_names=("visit_buy_conversion_rate",), + group_by_names=("metric_time", "visit__referrer_id"), + where_constraint=PydanticWhereFilter( + where_sql_template=("{{ Dimension('visit__referrer_id') }} = 'ref_id_01'") + ), + ) + dataflow_plan = dataflow_plan_builder.build_plan(parsed_query.query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_node, + ) + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric_with_time_constraint( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test rendering a query against a conversion metric with a time constraint and categorical filter.""" + parsed_query = query_parser.parse_and_validate_query( + metric_names=("visit_buy_conversion_rate",), + group_by_names=("visit__referrer_id",), + where_constraint=PydanticWhereFilter( + where_sql_template=("{{ Dimension('visit__referrer_id') }} = 'ref_id_01'") + ), + time_constraint_start=datetime.datetime(2020, 1, 1), + time_constraint_end=datetime.datetime(2020, 1, 2), + ) + dataflow_plan = dataflow_plan_builder.build_plan(parsed_query.query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_node, + ) + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric_with_window_and_time_constraint( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test rendering a query against a conversion metric with a window, time constraint, and categorical filter.""" + parsed_query = query_parser.parse_and_validate_query( + metric_names=("visit_buy_conversion_rate_7days",), + group_by_names=( + "metric_time", + "visit__referrer_id", + ), + where_constraint=PydanticWhereFilter( + where_sql_template=("{{ Dimension('visit__referrer_id') }} = 'ref_id_01'") + ), + time_constraint_start=datetime.datetime(2020, 1, 1), + time_constraint_end=datetime.datetime(2020, 1, 2), + ) + dataflow_plan = dataflow_plan_builder.build_plan(parsed_query.query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_node, + ) diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..f8475d5545 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS FLOAT64) / CAST(NULLIF(subq_15.visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GENERATE_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC(buys_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(buys_source_src_28000.ds, day) AS buy__ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS buy__ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS buy__ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS buy__ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS buy__ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + metric_time__day +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..a079495eec --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS FLOAT64) / CAST(NULLIF(visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC(ds, day) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC(ds, day) AS ds__day + , DATE_TRUNC(ds, day) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , 1 AS buys + , GENERATE_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + metric_time__day +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..fea6c7b2fb --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS FLOAT64) / CAST(NULLIF(subq_15.visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GENERATE_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC(buys_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(buys_source_src_28000.ds, day) AS buy__ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS buy__ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS buy__ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS buy__ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS buy__ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + metric_time__day + , visit__referrer_id +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..4bab3e4f64 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS FLOAT64) / CAST(NULLIF(visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC(ds, day) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC(ds, day) AS ds__day + , DATE_TRUNC(ds, day) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , 1 AS buys + , GENERATE_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + metric_time__day + , visit__referrer_id +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..d799fea526 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS FLOAT64) / CAST(NULLIF(subq_21.visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GENERATE_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC(buys_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(buys_source_src_28000.ds, day) AS buy__ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS buy__ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS buy__ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS buy__ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS buy__ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + visit__referrer_id +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..cd1b0725c9 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS FLOAT64) / CAST(NULLIF(visits, 0) AS FLOAT64) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC(ds, day) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC(ds, day) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , 1 AS buys + , GENERATE_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + visit__referrer_id +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..47325286aa --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS FLOAT64) / CAST(NULLIF(subq_15.visits, 0) AS FLOAT64) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GENERATE_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC(buys_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(buys_source_src_28000.ds, day) AS buy__ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS buy__ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS buy__ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS buy__ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS buy__ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > DATE_SUB(CAST(subq_10.ds__day AS DATETIME), INTERVAL 7 day) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + metric_time__day +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..e5b1d2d946 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS FLOAT64) / CAST(NULLIF(visits, 0) AS FLOAT64) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC(ds, day) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC(ds, day) AS ds__day + , DATE_TRUNC(ds, day) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , 1 AS buys + , GENERATE_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > DATE_SUB(CAST(subq_26.ds__day AS DATETIME), INTERVAL 7 day) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + metric_time__day +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..80a38a831d --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS FLOAT64) / CAST(NULLIF(subq_21.visits, 0) AS FLOAT64) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC(visits_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC(visits_source_src_28000.ds, day) AS visit__ds__day + , DATE_TRUNC(visits_source_src_28000.ds, isoweek) AS visit__ds__week + , DATE_TRUNC(visits_source_src_28000.ds, month) AS visit__ds__month + , DATE_TRUNC(visits_source_src_28000.ds, quarter) AS visit__ds__quarter + , DATE_TRUNC(visits_source_src_28000.ds, year) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , IF(EXTRACT(dayofweek FROM visits_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM visits_source_src_28000.ds) - 1) AS visit__ds__extract_dow + , EXTRACT(dayofyear FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GENERATE_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC(buys_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(buys_source_src_28000.ds, day) AS buy__ds__day + , DATE_TRUNC(buys_source_src_28000.ds, isoweek) AS buy__ds__week + , DATE_TRUNC(buys_source_src_28000.ds, month) AS buy__ds__month + , DATE_TRUNC(buys_source_src_28000.ds, quarter) AS buy__ds__quarter + , DATE_TRUNC(buys_source_src_28000.ds, year) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , IF(EXTRACT(dayofweek FROM buys_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM buys_source_src_28000.ds) - 1) AS buy__ds__extract_dow + , EXTRACT(dayofyear FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > DATE_SUB(CAST(subq_16.ds__day AS DATETIME), INTERVAL 7 day) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + metric_time__day + , visit__referrer_id +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..4c512fc780 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/BigQuery/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS FLOAT64) / CAST(NULLIF(visits, 0) AS FLOAT64) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC(ds, day) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC(ds, day) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC(ds, day) AS ds__day + , DATE_TRUNC(ds, day) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC(ds, day) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC(ds, day) AS ds__day + , user_id AS user + , 1 AS buys + , GENERATE_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > DATE_SUB(CAST(subq_34.ds__day AS DATETIME), INTERVAL 7 day) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + metric_time__day + , visit__referrer_id +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..b4e5a6c463 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..91c160f0b0 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..bf30d1b786 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..46eb6a9d43 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..abd7eb5465 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..b9cef550aa --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..fc5e6d8277 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > DATEADD(day, -7, subq_10.ds__day) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..e45ffc14a6 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > DATEADD(day, -7, subq_26.ds__day) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..334aa030cf --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > DATEADD(day, -7, subq_16.ds__day) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..edb59573fd --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Databricks/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > DATEADD(day, -7, subq_34.ds__day) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..e0da220e27 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..47741c1872 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..c381898ab3 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..bcaf6d1f75 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..7ea37e2248 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..6e26750751 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..56bba9dab9 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > subq_10.ds__day - INTERVAL 7 day + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..df8bba6a55 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > subq_26.ds__day - INTERVAL 7 day + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..c2d106c4f7 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > subq_16.ds__day - INTERVAL 7 day + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..075cabfbf2 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > subq_34.ds__day - INTERVAL 7 day + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..34510c1ee9 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..8f18aa1ad7 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..04384556ad --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..61872b05cc --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..f41b943ee9 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..d1e2485393 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..bc9e1d62f5 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > subq_10.ds__day - MAKE_INTERVAL(days => 7) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..30b04d6196 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > subq_26.ds__day - MAKE_INTERVAL(days => 7) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..df75c7f9fb --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(isodow FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(isodow FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > subq_16.ds__day - MAKE_INTERVAL(days => 7) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..d6d757e435 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Postgres/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > subq_34.ds__day - MAKE_INTERVAL(days => 7) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..ae4184f3ac --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..481b7de841 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..938052511a --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..a75a657c0e --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..756a827b2b --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..a7eb74d2bc --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..e3fa21809d --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > DATEADD(day, -7, subq_10.ds__day) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..a59248e42d --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > DATEADD(day, -7, subq_26.ds__day) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..a52fd49abb --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE PRECISION) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , CASE WHEN EXTRACT(dow FROM visits_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM visits_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM visits_source_src_28000.ds) END AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , CASE WHEN EXTRACT(dow FROM buys_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM buys_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM buys_source_src_28000.ds) END AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > DATEADD(day, -7, subq_16.ds__day) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..45dc1e63d6 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Redshift/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE PRECISION) / CAST(NULLIF(visits, 0) AS DOUBLE PRECISION) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , CONCAT(CAST(RANDOM()*100000000 AS INT)::VARCHAR,CAST(RANDOM()*100000000 AS INT)::VARCHAR) AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > DATEADD(day, -7, subq_34.ds__day) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..1d996f07ee --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID_STRING() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..986a1429eb --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID_STRING() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..1d36cea083 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID_STRING() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..ccff7e1173 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID_STRING() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..fef0bde96e --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , UUID_STRING() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..2b174bac0b --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID_STRING() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..0639bf329d --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , UUID_STRING() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > DATEADD(day, -7, subq_10.ds__day) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..ba1f391a5e --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID_STRING() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > DATEADD(day, -7, subq_26.ds__day) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..b06093216b --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(dayofweekiso FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , UUID_STRING() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(dayofweekiso FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > DATEADD(day, -7, subq_16.ds__day) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..f60942e548 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Snowflake/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN '2020-01-01' AND '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , UUID_STRING() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > DATEADD(day, -7, subq_34.ds__day) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0.sql new file mode 100644 index 0000000000..7630d246ae --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0.sql @@ -0,0 +1,391 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , uuid() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0_optimized.sql new file mode 100644 index 0000000000..6894661a08 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric__plan0_optimized.sql @@ -0,0 +1,110 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , uuid() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0.sql new file mode 100644 index 0000000000..fda80247b6 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0.sql @@ -0,0 +1,415 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , subq_15.visit__referrer_id + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) AS visit__referrer_id + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , subq_3.visit__referrer_id + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visit__referrer_id + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visit__referrer_id + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + , subq_3.visit__referrer_id + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , subq_13.visit__referrer_id + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.visit__referrer_id + , subq_12.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.visit__referrer_id + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.visit__referrer_id) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , uuid() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + (subq_7.ds__day <= subq_10.ds__day) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + , subq_13.visit__referrer_id + ) subq_14 + ON + ( + subq_4.visit__referrer_id = subq_14.visit__referrer_id + ) AND ( + subq_4.metric_time__day = subq_14.metric_time__day + ) + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) + , COALESCE(subq_4.visit__referrer_id, subq_14.visit__referrer_id) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0_optimized.sql new file mode 100644 index 0000000000..65e3e94782 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_categorical_filter__plan0_optimized.sql @@ -0,0 +1,131 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) AS visit__referrer_id + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.visit__referrer_id) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , uuid() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + (subq_23.ds__day <= subq_26.ds__day) + ) + ) subq_27 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_30 + ON + ( + subq_20.visit__referrer_id = subq_30.visit__referrer_id + ) AND ( + subq_20.metric_time__day = subq_30.metric_time__day + ) + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) + , COALESCE(subq_20.visit__referrer_id, subq_30.visit__referrer_id) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0.sql new file mode 100644 index 0000000000..928fef3d5f --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0.sql @@ -0,0 +1,483 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + SELECT + subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of INF + SELECT + subq_17.ds__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , uuid() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + (subq_13.ds__day <= subq_16.ds__day) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.visit__referrer_id + ) subq_20 + ON + subq_9.visit__referrer_id = subq_20.visit__referrer_id + GROUP BY + COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..c9a996be94 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_time_constraint__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id'] + SELECT + referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of INF + -- Pass Only Elements: ['buys', 'visit__referrer_id'] + -- Aggregate Measures + SELECT + visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , uuid() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + (subq_31.ds__day <= subq_34.ds__day) + ) + ) subq_35 + GROUP BY + visit__referrer_id + ) subq_38 + ON + subq_27.visit__referrer_id = subq_38.visit__referrer_id + GROUP BY + COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0.sql new file mode 100644 index 0000000000..17c1f0dadb --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0.sql @@ -0,0 +1,395 @@ +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__day + , CAST(subq_15.buys AS DOUBLE) / CAST(NULLIF(subq_15.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) AS metric_time__day + , MAX(subq_4.visits) AS visits + , MAX(subq_14.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_3.metric_time__day + , SUM(subq_3.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_2.metric_time__day + , subq_2.visits + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + subq_1.metric_time__day + , subq_1.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.visit__ds__day + , subq_0.visit__ds__week + , subq_0.visit__ds__month + , subq_0.visit__ds__quarter + , subq_0.visit__ds__year + , subq_0.visit__ds__extract_year + , subq_0.visit__ds__extract_quarter + , subq_0.visit__ds__extract_month + , subq_0.visit__ds__extract_day + , subq_0.visit__ds__extract_dow + , subq_0.visit__ds__extract_doy + , subq_0.ds__day AS metric_time__day + , subq_0.ds__week AS metric_time__week + , subq_0.ds__month AS metric_time__month + , subq_0.ds__quarter AS metric_time__quarter + , subq_0.ds__year AS metric_time__year + , subq_0.ds__extract_year AS metric_time__extract_year + , subq_0.ds__extract_quarter AS metric_time__extract_quarter + , subq_0.ds__extract_month AS metric_time__extract_month + , subq_0.ds__extract_day AS metric_time__extract_day + , subq_0.ds__extract_dow AS metric_time__extract_dow + , subq_0.ds__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.session + , subq_0.visit__user + , subq_0.visit__session + , subq_0.referrer_id + , subq_0.visit__referrer_id + , subq_0.visits + , subq_0.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_0 + ) subq_1 + ) subq_2 + WHERE metric_time__day = '2020-01-01' + ) subq_3 + GROUP BY + subq_3.metric_time__day + ) subq_4 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_13.metric_time__day + , SUM(subq_13.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'metric_time__day'] + SELECT + subq_12.metric_time__day + , subq_12.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_11.ds__day + , subq_11.metric_time__day + , subq_11.user + , subq_11.buys + , subq_11.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_7.visits) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_7.ds__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_7.metric_time__day) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_7.user) OVER ( + PARTITION BY + subq_10.user + , subq_10.ds__day + , subq_10.mf_internal_uuid + ORDER BY subq_7.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_10.mf_internal_uuid AS mf_internal_uuid + , subq_10.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_6.ds__day + , subq_6.metric_time__day + , subq_6.user + , subq_6.visits + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.ds__day AS metric_time__day + , subq_5.ds__week AS metric_time__week + , subq_5.ds__month AS metric_time__month + , subq_5.ds__quarter AS metric_time__quarter + , subq_5.ds__year AS metric_time__year + , subq_5.ds__extract_year AS metric_time__extract_year + , subq_5.ds__extract_quarter AS metric_time__extract_quarter + , subq_5.ds__extract_month AS metric_time__extract_month + , subq_5.ds__extract_day AS metric_time__extract_day + , subq_5.ds__extract_dow AS metric_time__extract_dow + , subq_5.ds__extract_doy AS metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_5 + ) subq_6 + ) subq_7 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_9.ds__day + , subq_9.ds__week + , subq_9.ds__month + , subq_9.ds__quarter + , subq_9.ds__year + , subq_9.ds__extract_year + , subq_9.ds__extract_quarter + , subq_9.ds__extract_month + , subq_9.ds__extract_day + , subq_9.ds__extract_dow + , subq_9.ds__extract_doy + , subq_9.buy__ds__day + , subq_9.buy__ds__week + , subq_9.buy__ds__month + , subq_9.buy__ds__quarter + , subq_9.buy__ds__year + , subq_9.buy__ds__extract_year + , subq_9.buy__ds__extract_quarter + , subq_9.buy__ds__extract_month + , subq_9.buy__ds__extract_day + , subq_9.buy__ds__extract_dow + , subq_9.buy__ds__extract_doy + , subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.metric_time__month + , subq_9.metric_time__quarter + , subq_9.metric_time__year + , subq_9.metric_time__extract_year + , subq_9.metric_time__extract_quarter + , subq_9.metric_time__extract_month + , subq_9.metric_time__extract_day + , subq_9.metric_time__extract_dow + , subq_9.metric_time__extract_doy + , subq_9.user + , subq_9.session_id + , subq_9.buy__user + , subq_9.buy__session_id + , subq_9.buys + , subq_9.buyers + , uuid() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.buy__ds__day + , subq_8.buy__ds__week + , subq_8.buy__ds__month + , subq_8.buy__ds__quarter + , subq_8.buy__ds__year + , subq_8.buy__ds__extract_year + , subq_8.buy__ds__extract_quarter + , subq_8.buy__ds__extract_month + , subq_8.buy__ds__extract_day + , subq_8.buy__ds__extract_dow + , subq_8.buy__ds__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys + , subq_8.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_8 + ) subq_9 + ) subq_10 + ON + ( + subq_7.user = subq_10.user + ) AND ( + ( + subq_7.ds__day <= subq_10.ds__day + ) AND ( + subq_7.ds__day > DATE_ADD('day', -7, subq_10.ds__day) + ) + ) + ) subq_11 + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__day + ) subq_14 + ON + subq_4.metric_time__day = subq_14.metric_time__day + GROUP BY + COALESCE(subq_4.metric_time__day, subq_14.metric_time__day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0_optimized.sql new file mode 100644 index 0000000000..630911bd4f --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window__plan0_optimized.sql @@ -0,0 +1,114 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) AS metric_time__day + , MAX(subq_20.visits) AS visits + , MAX(subq_30.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_18 + WHERE metric_time__day = '2020-01-01' + GROUP BY + metric_time__day + ) subq_20 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_23.visits) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_23.ds__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_23.metric_time__day) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_23.user) OVER ( + PARTITION BY + subq_26.user + , subq_26.ds__day + , subq_26.mf_internal_uuid + ORDER BY subq_23.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_26.mf_internal_uuid AS mf_internal_uuid + , subq_26.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_23 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , uuid() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_26 + ON + ( + subq_23.user = subq_26.user + ) AND ( + ( + subq_23.ds__day <= subq_26.ds__day + ) AND ( + subq_23.ds__day > DATE_ADD('day', -7, subq_26.ds__day) + ) + ) + ) subq_27 + GROUP BY + metric_time__day + ) subq_30 + ON + subq_20.metric_time__day = subq_30.metric_time__day + GROUP BY + COALESCE(subq_20.metric_time__day, subq_30.metric_time__day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0.sql new file mode 100644 index 0000000000..8f4d837d95 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0.sql @@ -0,0 +1,511 @@ +-- Compute Metrics via Expressions +SELECT + subq_21.metric_time__day + , subq_21.visit__referrer_id + , CAST(subq_21.buys AS DOUBLE) / CAST(NULLIF(subq_21.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) AS metric_time__day + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) AS visit__referrer_id + , MAX(subq_9.visits) AS visits + , MAX(subq_20.buys) AS buys + FROM ( + -- Aggregate Measures + SELECT + subq_8.metric_time__day + , subq_8.visit__referrer_id + , SUM(subq_8.visits) AS visits + FROM ( + -- Constrain Output with WHERE + SELECT + subq_7.metric_time__day + , subq_7.visit__referrer_id + , subq_7.visits + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_6.metric_time__day + , subq_6.visit__referrer_id + , subq_6.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_5.ds__day + , subq_5.ds__week + , subq_5.ds__month + , subq_5.ds__quarter + , subq_5.ds__year + , subq_5.ds__extract_year + , subq_5.ds__extract_quarter + , subq_5.ds__extract_month + , subq_5.ds__extract_day + , subq_5.ds__extract_dow + , subq_5.ds__extract_doy + , subq_5.visit__ds__day + , subq_5.visit__ds__week + , subq_5.visit__ds__month + , subq_5.visit__ds__quarter + , subq_5.visit__ds__year + , subq_5.visit__ds__extract_year + , subq_5.visit__ds__extract_quarter + , subq_5.visit__ds__extract_month + , subq_5.visit__ds__extract_day + , subq_5.visit__ds__extract_dow + , subq_5.visit__ds__extract_doy + , subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__month + , subq_5.metric_time__quarter + , subq_5.metric_time__year + , subq_5.metric_time__extract_year + , subq_5.metric_time__extract_quarter + , subq_5.metric_time__extract_month + , subq_5.metric_time__extract_day + , subq_5.metric_time__extract_dow + , subq_5.metric_time__extract_doy + , subq_5.user + , subq_5.session + , subq_5.visit__user + , subq_5.visit__session + , subq_5.referrer_id + , subq_5.visit__referrer_id + , subq_5.visits + , subq_5.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.visit__ds__day + , subq_4.visit__ds__week + , subq_4.visit__ds__month + , subq_4.visit__ds__quarter + , subq_4.visit__ds__year + , subq_4.visit__ds__extract_year + , subq_4.visit__ds__extract_quarter + , subq_4.visit__ds__extract_month + , subq_4.visit__ds__extract_day + , subq_4.visit__ds__extract_dow + , subq_4.visit__ds__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.user + , subq_4.session + , subq_4.visit__user + , subq_4.visit__session + , subq_4.referrer_id + , subq_4.visit__referrer_id + , subq_4.visits + , subq_4.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_4 + ) subq_5 + WHERE subq_5.metric_time__day BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_6 + ) subq_7 + WHERE visit__referrer_id = 'ref_id_01' + ) subq_8 + GROUP BY + subq_8.metric_time__day + , subq_8.visit__referrer_id + ) subq_9 + FULL OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_19.metric_time__day + , subq_19.visit__referrer_id + , SUM(subq_19.buys) AS buys + FROM ( + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + SELECT + subq_18.metric_time__day + , subq_18.visit__referrer_id + , subq_18.buys + FROM ( + -- Find conversions for user within the range of 7 day + SELECT + subq_17.ds__day + , subq_17.metric_time__day + , subq_17.user + , subq_17.visit__referrer_id + , subq_17.buys + , subq_17.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_13.visits) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_13.visit__referrer_id) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_13.ds__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_13.metric_time__day) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_13.user) OVER ( + PARTITION BY + subq_16.user + , subq_16.ds__day + , subq_16.mf_internal_uuid + ORDER BY subq_13.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_16.mf_internal_uuid AS mf_internal_uuid + , subq_16.buys AS buys + FROM ( + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + subq_12.ds__day + , subq_12.metric_time__day + , subq_12.user + , subq_12.visit__referrer_id + , subq_12.visits + FROM ( + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + SELECT + subq_11.ds__day + , subq_11.ds__week + , subq_11.ds__month + , subq_11.ds__quarter + , subq_11.ds__year + , subq_11.ds__extract_year + , subq_11.ds__extract_quarter + , subq_11.ds__extract_month + , subq_11.ds__extract_day + , subq_11.ds__extract_dow + , subq_11.ds__extract_doy + , subq_11.visit__ds__day + , subq_11.visit__ds__week + , subq_11.visit__ds__month + , subq_11.visit__ds__quarter + , subq_11.visit__ds__year + , subq_11.visit__ds__extract_year + , subq_11.visit__ds__extract_quarter + , subq_11.visit__ds__extract_month + , subq_11.visit__ds__extract_day + , subq_11.visit__ds__extract_dow + , subq_11.visit__ds__extract_doy + , subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__month + , subq_11.metric_time__quarter + , subq_11.metric_time__year + , subq_11.metric_time__extract_year + , subq_11.metric_time__extract_quarter + , subq_11.metric_time__extract_month + , subq_11.metric_time__extract_day + , subq_11.metric_time__extract_dow + , subq_11.metric_time__extract_doy + , subq_11.user + , subq_11.session + , subq_11.visit__user + , subq_11.visit__session + , subq_11.referrer_id + , subq_11.visit__referrer_id + , subq_11.visits + , subq_11.visitors + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_10.ds__day + , subq_10.ds__week + , subq_10.ds__month + , subq_10.ds__quarter + , subq_10.ds__year + , subq_10.ds__extract_year + , subq_10.ds__extract_quarter + , subq_10.ds__extract_month + , subq_10.ds__extract_day + , subq_10.ds__extract_dow + , subq_10.ds__extract_doy + , subq_10.visit__ds__day + , subq_10.visit__ds__week + , subq_10.visit__ds__month + , subq_10.visit__ds__quarter + , subq_10.visit__ds__year + , subq_10.visit__ds__extract_year + , subq_10.visit__ds__extract_quarter + , subq_10.visit__ds__extract_month + , subq_10.visit__ds__extract_day + , subq_10.visit__ds__extract_dow + , subq_10.visit__ds__extract_doy + , subq_10.ds__day AS metric_time__day + , subq_10.ds__week AS metric_time__week + , subq_10.ds__month AS metric_time__month + , subq_10.ds__quarter AS metric_time__quarter + , subq_10.ds__year AS metric_time__year + , subq_10.ds__extract_year AS metric_time__extract_year + , subq_10.ds__extract_quarter AS metric_time__extract_quarter + , subq_10.ds__extract_month AS metric_time__extract_month + , subq_10.ds__extract_day AS metric_time__extract_day + , subq_10.ds__extract_dow AS metric_time__extract_dow + , subq_10.ds__extract_doy AS metric_time__extract_doy + , subq_10.user + , subq_10.session + , subq_10.visit__user + , subq_10.visit__session + , subq_10.referrer_id + , subq_10.visit__referrer_id + , subq_10.visits + , subq_10.visitors + FROM ( + -- Read Elements From Semantic Model 'visits_source' + SELECT + 1 AS visits + , visits_source_src_28000.user_id AS visitors + , DATE_TRUNC('day', visits_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS ds__extract_doy + , visits_source_src_28000.referrer_id + , DATE_TRUNC('day', visits_source_src_28000.ds) AS visit__ds__day + , DATE_TRUNC('week', visits_source_src_28000.ds) AS visit__ds__week + , DATE_TRUNC('month', visits_source_src_28000.ds) AS visit__ds__month + , DATE_TRUNC('quarter', visits_source_src_28000.ds) AS visit__ds__quarter + , DATE_TRUNC('year', visits_source_src_28000.ds) AS visit__ds__year + , EXTRACT(year FROM visits_source_src_28000.ds) AS visit__ds__extract_year + , EXTRACT(quarter FROM visits_source_src_28000.ds) AS visit__ds__extract_quarter + , EXTRACT(month FROM visits_source_src_28000.ds) AS visit__ds__extract_month + , EXTRACT(day FROM visits_source_src_28000.ds) AS visit__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM visits_source_src_28000.ds) AS visit__ds__extract_dow + , EXTRACT(doy FROM visits_source_src_28000.ds) AS visit__ds__extract_doy + , visits_source_src_28000.referrer_id AS visit__referrer_id + , visits_source_src_28000.user_id AS user + , visits_source_src_28000.session_id AS session + , visits_source_src_28000.user_id AS visit__user + , visits_source_src_28000.session_id AS visit__session + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_10 + ) subq_11 + WHERE subq_11.metric_time__day BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_12 + ) subq_13 + INNER JOIN ( + -- Add column with generated UUID + SELECT + subq_15.ds__day + , subq_15.ds__week + , subq_15.ds__month + , subq_15.ds__quarter + , subq_15.ds__year + , subq_15.ds__extract_year + , subq_15.ds__extract_quarter + , subq_15.ds__extract_month + , subq_15.ds__extract_day + , subq_15.ds__extract_dow + , subq_15.ds__extract_doy + , subq_15.buy__ds__day + , subq_15.buy__ds__week + , subq_15.buy__ds__month + , subq_15.buy__ds__quarter + , subq_15.buy__ds__year + , subq_15.buy__ds__extract_year + , subq_15.buy__ds__extract_quarter + , subq_15.buy__ds__extract_month + , subq_15.buy__ds__extract_day + , subq_15.buy__ds__extract_dow + , subq_15.buy__ds__extract_doy + , subq_15.metric_time__day + , subq_15.metric_time__week + , subq_15.metric_time__month + , subq_15.metric_time__quarter + , subq_15.metric_time__year + , subq_15.metric_time__extract_year + , subq_15.metric_time__extract_quarter + , subq_15.metric_time__extract_month + , subq_15.metric_time__extract_day + , subq_15.metric_time__extract_dow + , subq_15.metric_time__extract_doy + , subq_15.user + , subq_15.session_id + , subq_15.buy__user + , subq_15.buy__session_id + , subq_15.buys + , subq_15.buyers + , uuid() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_14.ds__day + , subq_14.ds__week + , subq_14.ds__month + , subq_14.ds__quarter + , subq_14.ds__year + , subq_14.ds__extract_year + , subq_14.ds__extract_quarter + , subq_14.ds__extract_month + , subq_14.ds__extract_day + , subq_14.ds__extract_dow + , subq_14.ds__extract_doy + , subq_14.buy__ds__day + , subq_14.buy__ds__week + , subq_14.buy__ds__month + , subq_14.buy__ds__quarter + , subq_14.buy__ds__year + , subq_14.buy__ds__extract_year + , subq_14.buy__ds__extract_quarter + , subq_14.buy__ds__extract_month + , subq_14.buy__ds__extract_day + , subq_14.buy__ds__extract_dow + , subq_14.buy__ds__extract_doy + , subq_14.ds__day AS metric_time__day + , subq_14.ds__week AS metric_time__week + , subq_14.ds__month AS metric_time__month + , subq_14.ds__quarter AS metric_time__quarter + , subq_14.ds__year AS metric_time__year + , subq_14.ds__extract_year AS metric_time__extract_year + , subq_14.ds__extract_quarter AS metric_time__extract_quarter + , subq_14.ds__extract_month AS metric_time__extract_month + , subq_14.ds__extract_day AS metric_time__extract_day + , subq_14.ds__extract_dow AS metric_time__extract_dow + , subq_14.ds__extract_doy AS metric_time__extract_doy + , subq_14.user + , subq_14.session_id + , subq_14.buy__user + , subq_14.buy__session_id + , subq_14.buys + , subq_14.buyers + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , buys_source_src_28000.user_id AS buyers + , DATE_TRUNC('day', buys_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', buys_source_src_28000.ds) AS buy__ds__day + , DATE_TRUNC('week', buys_source_src_28000.ds) AS buy__ds__week + , DATE_TRUNC('month', buys_source_src_28000.ds) AS buy__ds__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds) AS buy__ds__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds) AS buy__ds__year + , EXTRACT(year FROM buys_source_src_28000.ds) AS buy__ds__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds) AS buy__ds__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds) AS buy__ds__extract_month + , EXTRACT(day FROM buys_source_src_28000.ds) AS buy__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM buys_source_src_28000.ds) AS buy__ds__extract_dow + , EXTRACT(doy FROM buys_source_src_28000.ds) AS buy__ds__extract_doy + , buys_source_src_28000.user_id AS user + , buys_source_src_28000.session_id + , buys_source_src_28000.user_id AS buy__user + , buys_source_src_28000.session_id AS buy__session_id + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_14 + ) subq_15 + ) subq_16 + ON + ( + subq_13.user = subq_16.user + ) AND ( + ( + subq_13.ds__day <= subq_16.ds__day + ) AND ( + subq_13.ds__day > DATE_ADD('day', -7, subq_16.ds__day) + ) + ) + ) subq_17 + ) subq_18 + ) subq_19 + GROUP BY + subq_19.metric_time__day + , subq_19.visit__referrer_id + ) subq_20 + ON + ( + subq_9.visit__referrer_id = subq_20.visit__referrer_id + ) AND ( + subq_9.metric_time__day = subq_20.metric_time__day + ) + GROUP BY + COALESCE(subq_9.metric_time__day, subq_20.metric_time__day) + , COALESCE(subq_9.visit__referrer_id, subq_20.visit__referrer_id) +) subq_21 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql new file mode 100644 index 0000000000..ba03cc4867 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/Trino/test_conversion_metric_with_window_and_time_constraint__plan0_optimized.sql @@ -0,0 +1,139 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__day + , visit__referrer_id + , CAST(buys AS DOUBLE) / CAST(NULLIF(visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_7days +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) AS metric_time__day + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) AS visit__referrer_id + , MAX(subq_27.visits) AS visits + , MAX(subq_38.buys) AS buys + FROM ( + -- Constrain Output with WHERE + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(visits) AS visits + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'metric_time__day'] + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_25 + WHERE visit__referrer_id = 'ref_id_01' + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_27 + FULL OUTER JOIN ( + -- Find conversions for user within the range of 7 day + -- Pass Only Elements: ['buys', 'visit__referrer_id', 'metric_time__day'] + -- Aggregate Measures + SELECT + metric_time__day + , visit__referrer_id + , SUM(buys) AS buys + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + first_value(subq_31.visits) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , first_value(subq_31.visit__referrer_id) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visit__referrer_id + , first_value(subq_31.ds__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__day + , first_value(subq_31.metric_time__day) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__day + , first_value(subq_31.user) OVER ( + PARTITION BY + subq_34.user + , subq_34.ds__day + , subq_34.mf_internal_uuid + ORDER BY subq_31.ds__day DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_34.mf_internal_uuid AS mf_internal_uuid + , subq_34.buys AS buys + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Constrain Time Range to [2020-01-01T00:00:00, 2020-01-02T00:00:00] + -- Pass Only Elements: ['visits', 'visit__referrer_id', 'ds__day', 'metric_time__day', 'user'] + SELECT + DATE_TRUNC('day', ds) AS ds__day + , DATE_TRUNC('day', ds) AS metric_time__day + , user_id AS user + , referrer_id AS visit__referrer_id + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + WHERE DATE_TRUNC('day', ds) BETWEEN timestamp '2020-01-01' AND timestamp '2020-01-02' + ) subq_31 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds' + -- Add column with generated UUID + SELECT + DATE_TRUNC('day', ds) AS ds__day + , user_id AS user + , 1 AS buys + , uuid() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_34 + ON + ( + subq_31.user = subq_34.user + ) AND ( + ( + subq_31.ds__day <= subq_34.ds__day + ) AND ( + subq_31.ds__day > DATE_ADD('day', -7, subq_34.ds__day) + ) + ) + ) subq_35 + GROUP BY + metric_time__day + , visit__referrer_id + ) subq_38 + ON + ( + subq_27.visit__referrer_id = subq_38.visit__referrer_id + ) AND ( + subq_27.metric_time__day = subq_38.metric_time__day + ) + GROUP BY + COALESCE(subq_27.metric_time__day, subq_38.metric_time__day) + , COALESCE(subq_27.visit__referrer_id, subq_38.visit__referrer_id) +) subq_39