diff --git a/metricflow/test/fixtures/model_yamls/simple_model/data_sources/buys_source.yaml b/metricflow/test/fixtures/model_yamls/simple_model/data_sources/buys_source.yaml index 5609232d9c..7d8043b836 100644 --- a/metricflow/test/fixtures/model_yamls/simple_model/data_sources/buys_source.yaml +++ b/metricflow/test/fixtures/model_yamls/simple_model/data_sources/buys_source.yaml @@ -28,3 +28,5 @@ data_source: - name: user type: foreign expr: user_id + - name: session_id + type: foreign diff --git a/metricflow/test/fixtures/model_yamls/simple_model/data_sources/visits_source.yaml b/metricflow/test/fixtures/model_yamls/simple_model/data_sources/visits_source.yaml index 9a517b1785..f355f8a71d 100644 --- a/metricflow/test/fixtures/model_yamls/simple_model/data_sources/visits_source.yaml +++ b/metricflow/test/fixtures/model_yamls/simple_model/data_sources/visits_source.yaml @@ -30,4 +30,7 @@ data_source: identifiers: - name: user type: foreign - expr: user_id \ No newline at end of file + expr: user_id + - name: session + type: foreign + expr: session_id \ No newline at end of file diff --git a/metricflow/test/fixtures/model_yamls/simple_model/metrics.yaml b/metricflow/test/fixtures/model_yamls/simple_model/metrics.yaml index ea6bb140b2..23dbaf20b9 100644 --- a/metricflow/test/fixtures/model_yamls/simple_model/metrics.yaml +++ b/metricflow/test/fixtures/model_yamls/simple_model/metrics.yaml @@ -710,3 +710,20 @@ metric: window: 7 days entity: user calculation: conversions +--- +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 + owners: + - support@transformdata.io + type: conversion + type_params: + conversion_type_params: + base_measure: visits + conversion_measure: buys + window: 7 days + entity: user + calculation: conversion_rate + constant_properties: + - name: session_id + base_expr: session diff --git a/metricflow/test/fixtures/table_fixtures.py b/metricflow/test/fixtures/table_fixtures.py index 19afb34046..f955108d2e 100644 --- a/metricflow/test/fixtures/table_fixtures.py +++ b/metricflow/test/fixtures/table_fixtures.py @@ -331,23 +331,23 @@ def create_simple_model_tables(mf_test_session_state: MetricFlowTestSessionState # Events data visits_data = [ - ("u0004114", "2020-01-01", "fb_ad_1"), - ("u0004214", "2020-01-01", "fb_ad_2"), - ("u0003141", "2020-01-01", "homepage_1"), - ("u0003154", "2020-01-01", "homepage_2"), - ("u1612112", "2020-01-02", "homepage_1"), - ("u0042324", "2020-01-02", "homepage_1"), - ("u0005432", "2020-01-02", "fb_ad_3"), - ("u0003452", "2020-01-02", "fb_ad_1"), - ("u0003452", "2020-01-02", "user_2"), - ("u0042324", "2020-01-03", "fb_ad_1"), - ("u0005432", "2020-01-03", "google_ad_1"), - ("u0005472", "2020-01-03", "google_ad_2"), - ("u0005414", "2020-01-04", "google_ad_1"), - ("u0004114", "2020-01-06", "homepage_1"), - ("u0004114", "2020-01-07", "fb_ad_2"), - ("u0004117", "2020-01-10", "google_ad_1"), - ("u0003141", "2020-01-12", "user_1"), + ("u0004114", "2020-01-01", "fb_ad_1", "s1"), + ("u0004214", "2020-01-01", "fb_ad_2", "s2"), + ("u0003141", "2020-01-01", "homepage_1", "s3"), + ("u0003154", "2020-01-01", "homepage_2", "s4"), + ("u1612112", "2020-01-02", "homepage_1", "s5"), + ("u0042324", "2020-01-02", "homepage_1", "s6"), + ("u0005432", "2020-01-02", "fb_ad_3", "s7"), + ("u0003452", "2020-01-02", "fb_ad_1", "s8"), + ("u0003452", "2020-01-02", "user_2", "s8"), + ("u0042324", "2020-01-03", "fb_ad_1", "s9"), + ("u0005432", "2020-01-03", "google_ad_1", "s10"), + ("u0005472", "2020-01-03", "google_ad_2", "s11"), + ("u0005414", "2020-01-04", "google_ad_1", "s12"), + ("u0004114", "2020-01-06", "homepage_1", "s13"), + ("u0004114", "2020-01-07", "fb_ad_2", "s14"), + ("u0004117", "2020-01-10", "google_ad_1", "s15"), + ("u0003141", "2020-01-12", "user_1", "s16"), ] create_table( @@ -355,22 +355,22 @@ def create_simple_model_tables(mf_test_session_state: MetricFlowTestSessionState sql_table=SqlTable(schema_name=schema, table_name="fct_visits"), df=make_df( sql_client=sql_client, - columns=["user_id", DEFAULT_DS, "referrer_id"], + columns=["user_id", DEFAULT_DS, "referrer_id", "session_id"], time_columns={DEFAULT_DS}, data=visits_data, ), ) buy_data = [ - ("u0004114", "2020-01-02"), - ("u0042324", "2020-01-03"), - ("u0042324", "2020-01-03"), - ("u0005432", "2020-01-04"), - ("u1612112", "2020-01-07"), - ("u0004114", "2020-01-07"), - ("u0004117", "2020-01-10"), - ("u0003141", "2020-01-07"), - ("u0003452", "2020-01-04"), + ("u0004114", "2020-01-02", "s1"), + ("u0042324", "2020-01-03", "s6"), + ("u0042324", "2020-01-03", "s9"), + ("u0005432", "2020-01-04", "s7"), + ("u1612112", "2020-01-07", "s0"), + ("u0004114", "2020-01-07", "s14"), + ("u0004117", "2020-01-10", "s15"), + ("u0003141", "2020-01-07", "s3"), + ("u0003452", "2020-01-04", "s8"), ] create_table( @@ -378,7 +378,7 @@ def create_simple_model_tables(mf_test_session_state: MetricFlowTestSessionState sql_table=SqlTable(schema_name=schema, table_name="fct_buys"), df=make_df( sql_client=sql_client, - columns=["user_id", DEFAULT_DS], + columns=["user_id", DEFAULT_DS, "session_id"], time_columns={DEFAULT_DS}, data=buy_data, ), diff --git a/metricflow/test/integration/test_cases/itest_conversion_metrics.yaml b/metricflow/test/integration/test_cases/itest_conversion_metrics.yaml index 5a153e8130..9b095b4901 100644 --- a/metricflow/test/integration/test_cases/itest_conversion_metrics.yaml +++ b/metricflow/test/integration/test_cases/itest_conversion_metrics.yaml @@ -228,3 +228,49 @@ integration_test: GROUP BY b.referrer_id, b.ds ) conversions +--- +integration_test: + name: conversion_rate_metric_with_constant_property + description: Query a conversion metric that calculates the conversion rate held by a constant property + model: SIMPLE_MODEL + metrics: ["visit_buy_conversion_rate_by_session"] + group_bys: ["metric_time"] + check_query: | + SELECT + opportunities.metric_time AS metric_time + , CAST(conversions.buys AS {{ double_data_type_name }}) / CAST(NULLIF(opportunities.visits, 0) AS {{ double_data_type_name }}) AS visit_buy_conversion_rate_by_session + FROM ( + SELECT + metric_time, SUM(a.visits) AS visits + FROM ( + SELECT + ds AS metric_time, 1 AS visits + FROM {{ source_schema }}.fct_visits visits + ) a + GROUP BY + a.metric_time + ) opportunities + INNER JOIN ( + SELECT + b.ds AS metric_time, SUM(b.buys) AS buys + FROM ( + SELECT DISTINCT + first_value(v.ds) OVER (PARTITION BY buy_source.ds, buy_source.user_id, buy_source.session_id ORDER BY v.ds DESC NULLS FIRST) AS ds + , first_value(v.user_id) OVER (PARTITION BY buy_source.ds, buy_source.user_id, buy_source.session_id ORDER BY v.ds DESC NULLS FIRST) AS user_id + , first_value(v.referrer_id) OVER (PARTITION BY buy_source.ds, buy_source.user_id, buy_source.session_id ORDER BY v.ds DESC NULLS FIRST) AS referrer_id + , buy_source.uuid + , 1 AS buys + FROM {{ source_schema }}.fct_visits v + INNER JOIN + ( + SELECT *, {{ generate_random_uuid() }} AS uuid FROM {{ source_schema }}.fct_buys + ) buy_source + ON + v.user_id = buy_source.user_id + AND v.ds <= buy_source.ds AND v.ds > {{ render_date_sub("buy_source", "ds", 7, TimeGranularity.DAY) }} + AND buy_source.session_id = v.session_id + ) b + GROUP BY + b.ds + ) conversions + ON opportunities.metric_time = conversions.metric_time \ No newline at end of file