diff --git a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml index e3ddb2998a..d544876992 100644 --- a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml +++ b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml @@ -594,6 +594,18 @@ metric: entity: user calculation: conversions --- +metric: + name: visit_buy_conversion_rate_with_monthly_conversion + description: conversion rate on visits-buys_month + type: conversion + type_params: + conversion_type_params: + base_measure: visits + conversion_measure: buys_month + entity: user + calculation: conversion_rate + window: 1 month +--- metric: name: visit_buy_conversion_rate_by_session description: conversion rate on visits-buys on a 7 day window held by a constant session_id diff --git a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/buys_source.yaml b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/buys_source.yaml index fd0eb1d2f2..6aa6601f6a 100644 --- a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/buys_source.yaml +++ b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/buys_source.yaml @@ -14,6 +14,10 @@ semantic_model: - name: buys expr: 1 agg: count + - name: buys_month + expr: 1 + agg: count + agg_time_dimension: ds_month - name: buyers expr: user_id agg: count_distinct @@ -23,6 +27,10 @@ semantic_model: type: time type_params: time_granularity: day + - name: ds_month + type: time + type_params: + time_granularity: month primary_entity: buy diff --git a/tests_metricflow/fixtures/source_table_snapshots/simple_model/fct_buys.yaml b/tests_metricflow/fixtures/source_table_snapshots/simple_model/fct_buys.yaml index 75e198829c..8f29d0d1eb 100644 --- a/tests_metricflow/fixtures/source_table_snapshots/simple_model/fct_buys.yaml +++ b/tests_metricflow/fixtures/source_table_snapshots/simple_model/fct_buys.yaml @@ -3,16 +3,18 @@ table_snapshot: column_definitions: - name: ds type: TIME + - name: ds_month + type: TIME - name: user_id type: STRING - name: session_id type: STRING rows: - - ["2020-01-02", "u0004114", "s1"] - - ["2020-01-03", "u0042324", "s9"] - - ["2020-01-04", "u0005432", "s6"] - - ["2020-01-04", "u0003452", "s7"] - - ["2020-01-07", "u1612112", "s123"] - - ["2020-01-07", "u0004114", "s14"] - - ["2020-01-07", "u0003141", "s3"] - - ["2020-01-10", "u0004117", "s15"] + - ["2020-01-02", "2020-01-01", "u0004114", "s1"] + - ["2020-01-03", "2020-01-01", "u0042324", "s9"] + - ["2020-01-04", "2020-01-01", "u0005432", "s6"] + - ["2020-01-04", "2020-01-01", "u0003452", "s7"] + - ["2020-01-07", "2020-01-01", "u1612112", "s123"] + - ["2020-01-07", "2020-01-01", "u0004114", "s14"] + - ["2020-01-07", "2020-01-01", "u0003141", "s3"] + - ["2020-01-10", "2020-01-01", "u0004117", "s15"] diff --git a/tests_metricflow/query_rendering/test_conversion_metric_rendering.py b/tests_metricflow/query_rendering/test_conversion_metric_rendering.py index 9f7e4c74fa..f9456a7680 100644 --- a/tests_metricflow/query_rendering/test_conversion_metric_rendering.py +++ b/tests_metricflow/query_rendering/test_conversion_metric_rendering.py @@ -220,3 +220,28 @@ def test_conversion_metric_with_filter_not_in_group_by( dataflow_plan_builder=dataflow_plan_builder, query_spec=parsed_query.query_spec, ) + + +@pytest.mark.sql_engine_snapshot +def test_conversion_metric_with_different_time_dimension_grains( + 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_with_monthly_conversion",), + ) + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=parsed_query.query_spec, + ) diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0.sql new file mode 100644 index 0000000000..c4b59626e1 --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0.sql @@ -0,0 +1,389 @@ +-- Compute Metrics via Expressions +SELECT + CAST(subq_14.buys_month AS DOUBLE) / CAST(NULLIF(subq_14.visits, 0) AS DOUBLE) AS visit_buy_conversion_rate_with_monthly_conversion +FROM ( + -- Combine Aggregated Outputs + SELECT + MAX(subq_3.visits) AS visits + , MAX(subq_13.buys_month) AS buys_month + FROM ( + -- Aggregate Measures + SELECT + SUM(subq_2.visits) AS visits + FROM ( + -- Pass Only Elements: ['visits',] + SELECT + 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 + ) subq_3 + CROSS JOIN ( + -- Aggregate Measures + SELECT + SUM(subq_12.buys_month) AS buys_month + FROM ( + -- Pass Only Elements: ['buys_month',] + SELECT + subq_11.buys_month + FROM ( + -- Find conversions for user within the range of 1 month + SELECT + subq_10.metric_time__month + , subq_10.user + , subq_10.buys_month + , subq_10.visits + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + FIRST_VALUE(subq_6.visits) OVER ( + PARTITION BY + subq_9.user + , subq_9.metric_time__month + , subq_9.mf_internal_uuid + ORDER BY subq_6.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , FIRST_VALUE(subq_6.metric_time__month) OVER ( + PARTITION BY + subq_9.user + , subq_9.metric_time__month + , subq_9.mf_internal_uuid + ORDER BY subq_6.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__month + , FIRST_VALUE(subq_6.user) OVER ( + PARTITION BY + subq_9.user + , subq_9.metric_time__month + , subq_9.mf_internal_uuid + ORDER BY subq_6.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_9.mf_internal_uuid AS mf_internal_uuid + , subq_9.buys_month AS buys_month + FROM ( + -- Pass Only Elements: ['visits', 'metric_time__month', 'user'] + SELECT + subq_5.metric_time__month + , subq_5.user + , subq_5.visits + 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 + ) subq_6 + INNER JOIN ( + -- Add column with generated UUID + 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.ds_month__month + , subq_8.ds_month__quarter + , subq_8.ds_month__year + , subq_8.ds_month__extract_year + , subq_8.ds_month__extract_quarter + , subq_8.ds_month__extract_month + , 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.buy__ds_month__month + , subq_8.buy__ds_month__quarter + , subq_8.buy__ds_month__year + , subq_8.buy__ds_month__extract_year + , subq_8.buy__ds_month__extract_quarter + , subq_8.buy__ds_month__extract_month + , subq_8.metric_time__month + , subq_8.metric_time__quarter + , subq_8.metric_time__year + , subq_8.metric_time__extract_year + , subq_8.metric_time__extract_quarter + , subq_8.metric_time__extract_month + , subq_8.user + , subq_8.session_id + , subq_8.buy__user + , subq_8.buy__session_id + , subq_8.buys_month + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ( + -- Metric Time Dimension 'ds_month' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_month__month + , subq_7.ds_month__quarter + , subq_7.ds_month__year + , subq_7.ds_month__extract_year + , subq_7.ds_month__extract_quarter + , subq_7.ds_month__extract_month + , subq_7.buy__ds__day + , subq_7.buy__ds__week + , subq_7.buy__ds__month + , subq_7.buy__ds__quarter + , subq_7.buy__ds__year + , subq_7.buy__ds__extract_year + , subq_7.buy__ds__extract_quarter + , subq_7.buy__ds__extract_month + , subq_7.buy__ds__extract_day + , subq_7.buy__ds__extract_dow + , subq_7.buy__ds__extract_doy + , subq_7.buy__ds_month__month + , subq_7.buy__ds_month__quarter + , subq_7.buy__ds_month__year + , subq_7.buy__ds_month__extract_year + , subq_7.buy__ds_month__extract_quarter + , subq_7.buy__ds_month__extract_month + , subq_7.ds_month__month AS metric_time__month + , subq_7.ds_month__quarter AS metric_time__quarter + , subq_7.ds_month__year AS metric_time__year + , subq_7.ds_month__extract_year AS metric_time__extract_year + , subq_7.ds_month__extract_quarter AS metric_time__extract_quarter + , subq_7.ds_month__extract_month AS metric_time__extract_month + , subq_7.user + , subq_7.session_id + , subq_7.buy__user + , subq_7.buy__session_id + , subq_7.buys_month + FROM ( + -- Read Elements From Semantic Model 'buys_source' + SELECT + 1 AS buys + , 1 AS buys_month + , 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('month', buys_source_src_28000.ds_month) AS ds_month__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds_month) AS ds_month__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds_month) AS ds_month__year + , EXTRACT(year FROM buys_source_src_28000.ds_month) AS ds_month__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds_month) AS ds_month__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds_month) AS ds_month__extract_month + , 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 + , DATE_TRUNC('month', buys_source_src_28000.ds_month) AS buy__ds_month__month + , DATE_TRUNC('quarter', buys_source_src_28000.ds_month) AS buy__ds_month__quarter + , DATE_TRUNC('year', buys_source_src_28000.ds_month) AS buy__ds_month__year + , EXTRACT(year FROM buys_source_src_28000.ds_month) AS buy__ds_month__extract_year + , EXTRACT(quarter FROM buys_source_src_28000.ds_month) AS buy__ds_month__extract_quarter + , EXTRACT(month FROM buys_source_src_28000.ds_month) AS buy__ds_month__extract_month + , 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_7 + ) subq_8 + ) subq_9 + ON + ( + subq_6.user = subq_9.user + ) AND ( + ( + subq_6.metric_time__month <= subq_9.metric_time__month + ) AND ( + subq_6.metric_time__month > subq_9.metric_time__month - INTERVAL 1 month + ) + ) + ) subq_10 + ) subq_11 + ) subq_12 + ) subq_13 +) subq_14 diff --git a/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0_optimized.sql new file mode 100644 index 0000000000..85a9e03a3a --- /dev/null +++ b/tests_metricflow/snapshots/test_conversion_metric_rendering.py/SqlQueryPlan/DuckDB/test_conversion_metric_with_different_time_dimension_grains__plan0_optimized.sql @@ -0,0 +1,81 @@ +-- Combine Aggregated Outputs +-- Compute Metrics via Expressions +SELECT + CAST(MAX(subq_28.buys_month) AS DOUBLE) / CAST(NULLIF(MAX(subq_18.visits), 0) AS DOUBLE) AS visit_buy_conversion_rate_with_monthly_conversion +FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits',] + -- Aggregate Measures + SELECT + SUM(1) AS visits + FROM ***************************.fct_visits visits_source_src_28000 +) subq_18 +CROSS JOIN ( + -- Find conversions for user within the range of 1 month + -- Pass Only Elements: ['buys_month',] + -- Aggregate Measures + SELECT + SUM(buys_month) AS buys_month + FROM ( + -- Dedupe the fanout with mf_internal_uuid in the conversion data set + SELECT DISTINCT + FIRST_VALUE(subq_21.visits) OVER ( + PARTITION BY + subq_24.user + , subq_24.metric_time__month + , subq_24.mf_internal_uuid + ORDER BY subq_21.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS visits + , FIRST_VALUE(subq_21.metric_time__month) OVER ( + PARTITION BY + subq_24.user + , subq_24.metric_time__month + , subq_24.mf_internal_uuid + ORDER BY subq_21.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS metric_time__month + , FIRST_VALUE(subq_21.user) OVER ( + PARTITION BY + subq_24.user + , subq_24.metric_time__month + , subq_24.mf_internal_uuid + ORDER BY subq_21.metric_time__month DESC + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS user + , subq_24.mf_internal_uuid AS mf_internal_uuid + , subq_24.buys_month AS buys_month + FROM ( + -- Read Elements From Semantic Model 'visits_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['visits', 'metric_time__month', 'user'] + SELECT + DATE_TRUNC('month', ds) AS metric_time__month + , user_id AS user + , 1 AS visits + FROM ***************************.fct_visits visits_source_src_28000 + ) subq_21 + INNER JOIN ( + -- Read Elements From Semantic Model 'buys_source' + -- Metric Time Dimension 'ds_month' + -- Add column with generated UUID + SELECT + DATE_TRUNC('month', ds_month) AS metric_time__month + , user_id AS user + , 1 AS buys_month + , GEN_RANDOM_UUID() AS mf_internal_uuid + FROM ***************************.fct_buys buys_source_src_28000 + ) subq_24 + ON + ( + subq_21.user = subq_24.user + ) AND ( + ( + subq_21.metric_time__month <= subq_24.metric_time__month + ) AND ( + subq_21.metric_time__month > subq_24.metric_time__month - INTERVAL 1 month + ) + ) + ) subq_25 +) subq_28