From 7fc74c0009554a9851e2a56b67b44be8b04bf499 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 15:24:18 -0700 Subject: [PATCH 01/26] Refactor _make_time_spine_data_set() for readability & simplicity Also supports an upcoming change to allow multiple agg_time_dimensions in this function. --- metricflow/plan_conversion/dataflow_to_sql.py | 120 ++++++------------ metricflow/sql/sql_exprs.py | 4 + 2 files changed, 46 insertions(+), 78 deletions(-) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 4413b9e8b5..bd6a4567ce 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -223,89 +223,59 @@ def _next_unique_table_alias(self) -> str: def _make_time_spine_data_set( self, agg_time_dimension_instance: TimeDimensionInstance, - agg_time_dimension_column_name: str, time_spine_source: TimeSpineSource, time_range_constraint: Optional[TimeRangeConstraint] = None, ) -> SqlDataSet: - """Make a time spine data set, which contains all date values like '2020-01-01', '2020-01-02'... + """Make a time spine data set, which contains all date/time values like '2020-01-01', '2020-01-02'... - This is useful in computing cumulative metrics. This will need to be updated to support granularities finer than a - day. + Returns a data set with a column for the agg_time_dimension requested. + Column alias will use 'metric_time' or the agg_time_dimension name depending on which the user requested. """ - time_spine_instance = TimeDimensionInstance( - defined_from=agg_time_dimension_instance.defined_from, - associated_columns=(ColumnAssociation(agg_time_dimension_column_name),), - spec=agg_time_dimension_instance.spec, - ) - - time_spine_instance_set = InstanceSet(time_dimension_instances=(time_spine_instance,)) + time_spine_instance_set = InstanceSet(time_dimension_instances=(agg_time_dimension_instance,)) time_spine_table_alias = self._next_unique_table_alias() - # If the requested granularity is the same as the granularity of the spine, do a direct select. + column_expr = SqlColumnReferenceExpression.from_table_and_column_names( + table_alias=time_spine_table_alias, column_name=time_spine_source.time_column_name + ) + + select_columns: Tuple[SqlSelectColumn, ...] = () + apply_group_by = False + column_alias = self.column_association_resolver.resolve_spec(agg_time_dimension_instance.spec).column_name + # If the requested granularity matches that of the time spine, do a direct select. + # TODO: also handle date part. if agg_time_dimension_instance.spec.time_granularity == time_spine_source.time_column_granularity: - return SqlDataSet( - instance_set=time_spine_instance_set, - sql_select_node=SqlSelectStatementNode( - description=TIME_SPINE_DATA_SET_DESCRIPTION, - select_columns=( - SqlSelectColumn( - expr=SqlColumnReferenceExpression( - SqlColumnReference( - table_alias=time_spine_table_alias, - column_name=time_spine_source.time_column_name, - ), - ), - column_alias=agg_time_dimension_column_name, - ), - ), - from_source=SqlTableFromClauseNode(sql_table=time_spine_source.spine_table), - from_source_alias=time_spine_table_alias, - where=( - _make_time_range_comparison_expr( - table_alias=time_spine_table_alias, - column_alias=time_spine_source.time_column_name, - time_range_constraint=time_range_constraint, - ) - if time_range_constraint - else None - ), - ), - ) - # If the granularity is different, apply a DATE_TRUNC() and aggregate. + select_columns += (SqlSelectColumn(expr=column_expr, column_alias=column_alias),) + # Otherwise, apply a DATE_TRUNC() and aggregate via group_by. else: - select_columns = ( + select_columns += ( SqlSelectColumn( expr=SqlDateTruncExpression( - time_granularity=agg_time_dimension_instance.spec.time_granularity, - arg=SqlColumnReferenceExpression( - SqlColumnReference( - table_alias=time_spine_table_alias, - column_name=time_spine_source.time_column_name, - ), - ), + time_granularity=agg_time_dimension_instance.spec.time_granularity, arg=column_expr ), - column_alias=agg_time_dimension_column_name, + column_alias=column_alias, ), ) - return SqlDataSet( - instance_set=time_spine_instance_set, - sql_select_node=SqlSelectStatementNode( - description=TIME_SPINE_DATA_SET_DESCRIPTION, - select_columns=select_columns, - from_source=SqlTableFromClauseNode(sql_table=time_spine_source.spine_table), - from_source_alias=time_spine_table_alias, - group_bys=select_columns, - where=( - _make_time_range_comparison_expr( - table_alias=time_spine_table_alias, - column_alias=time_spine_source.time_column_name, - time_range_constraint=time_range_constraint, - ) - if time_range_constraint - else None - ), + apply_group_by = True + + return SqlDataSet( + instance_set=time_spine_instance_set, + sql_select_node=SqlSelectStatementNode( + description=TIME_SPINE_DATA_SET_DESCRIPTION, + select_columns=select_columns, + from_source=SqlTableFromClauseNode(sql_table=time_spine_source.spine_table), + from_source_alias=time_spine_table_alias, + group_bys=select_columns if apply_group_by else (), + where=( + _make_time_range_comparison_expr( + table_alias=time_spine_table_alias, + column_alias=time_spine_source.time_column_name, + time_range_constraint=time_range_constraint, + ) + if time_range_constraint + else None ), - ) + ), + ) def visit_source_node(self, node: ReadSqlSourceNode) -> SqlDataSet: """Generate the SQL to read from the source.""" @@ -332,15 +302,10 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat time_spine_data_set_alias = self._next_unique_table_alias() - agg_time_dimension_column_name = self.column_association_resolver.resolve_spec( - agg_time_dimension_instance.spec - ).column_name - # Assemble time_spine dataset with metric_time_dimension to join. # Granularity of time_spine column should match granularity of metric_time column from parent dataset. time_spine_data_set = self._make_time_spine_data_set( agg_time_dimension_instance=agg_time_dimension_instance, - agg_time_dimension_column_name=agg_time_dimension_column_name, time_spine_source=self._time_spine_source, time_range_constraint=node.time_range_constraint, ) @@ -1275,22 +1240,21 @@ def visit_join_to_time_spine_node(self, node: JoinToTimeSpineNode) -> SqlDataSet agg_time_dimension_instance_for_join = agg_time_dimension_instances[0] # Build time spine data set using the requested agg_time_dimension name. - agg_time_dimension_column_name = self.column_association_resolver.resolve_spec( - agg_time_dimension_instance_for_join.spec - ).column_name time_spine_alias = self._next_unique_table_alias() time_spine_dataset = self._make_time_spine_data_set( agg_time_dimension_instance=agg_time_dimension_instance_for_join, - agg_time_dimension_column_name=agg_time_dimension_column_name, time_spine_source=self._time_spine_source, time_range_constraint=node.time_range_constraint, ) # Build join expression. + join_description = SqlQueryPlanJoinBuilder.make_join_to_time_spine_join_description( node=node, time_spine_alias=time_spine_alias, - agg_time_dimension_column_name=agg_time_dimension_column_name, + agg_time_dimension_column_name=self.column_association_resolver.resolve_spec( + agg_time_dimension_instance_for_join.spec + ).column_name, parent_sql_select_node=parent_data_set.checked_sql_select_node, parent_alias=parent_alias, ) diff --git a/metricflow/sql/sql_exprs.py b/metricflow/sql/sql_exprs.py index 0d1f598abe..3a1f424822 100644 --- a/metricflow/sql/sql_exprs.py +++ b/metricflow/sql/sql_exprs.py @@ -476,6 +476,10 @@ def matches(self, other: SqlExpressionNode) -> bool: # noqa: D102 return False return self.col_ref == other.col_ref + @staticmethod + def from_table_and_column_names(table_alias: str, column_name: str) -> SqlColumnReferenceExpression: # noqa: D102 + return SqlColumnReferenceExpression(SqlColumnReference(table_alias=table_alias, column_name=column_name)) + class SqlColumnAliasReferenceExpression(SqlExpressionNode): """An expression that evaluates to the alias of a column, but is not qualified with a table alias. From ad7c2bc7c203da0909b8d32cad241d1495895d8e Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 15:33:10 -0700 Subject: [PATCH 02/26] Refactor JoinOverTimeRangeNode SQL rendering for readability & simplicity Also supports an upcoming change to allow multiple agg_time_dimensions in this node. --- metricflow/plan_conversion/dataflow_to_sql.py | 58 ++++++------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index bd6a4567ce..41cd70a701 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -287,7 +287,6 @@ def visit_source_node(self, node: ReadSqlSourceNode) -> SqlDataSet: def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDataSet: """Generate time range join SQL.""" table_alias_to_instance_set: OrderedDict[str, InstanceSet] = OrderedDict() - input_data_set = node.parent_node.accept(self) input_data_set_alias = self._next_unique_table_alias() @@ -302,8 +301,7 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat time_spine_data_set_alias = self._next_unique_table_alias() - # Assemble time_spine dataset with metric_time_dimension to join. - # Granularity of time_spine column should match granularity of metric_time column from parent dataset. + # Assemble time_spine dataset with agg_time_dimension_instance selected. time_spine_data_set = self._make_time_spine_data_set( agg_time_dimension_instance=agg_time_dimension_instance, time_spine_source=self._time_spine_source, @@ -311,44 +309,27 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat ) table_alias_to_instance_set[time_spine_data_set_alias] = time_spine_data_set.instance_set - # Figure out which columns correspond to the time dimension that we want to join on. - input_data_set_metric_time_column_association = input_data_set.column_association_for_time_dimension( - agg_time_dimension_instance.spec - ) - input_data_set_metric_time_col = input_data_set_metric_time_column_association.column_name - - time_spine_data_set_column_associations = time_spine_data_set.column_association_for_time_dimension( - agg_time_dimension_instance.spec - ) - time_spine_data_set_time_dimension_col = time_spine_data_set_column_associations.column_name - - annotated_input_data_set = AnnotatedSqlDataSet( - data_set=input_data_set, alias=input_data_set_alias, _metric_time_column_name=input_data_set_metric_time_col - ) - annotated_time_spine_data_set = AnnotatedSqlDataSet( - data_set=time_spine_data_set, - alias=time_spine_data_set_alias, - _metric_time_column_name=time_spine_data_set_time_dimension_col, - ) - join_desc = SqlQueryPlanJoinBuilder.make_cumulative_metric_time_range_join_description( - node=node, metric_data_set=annotated_input_data_set, time_spine_data_set=annotated_time_spine_data_set + node=node, + metric_data_set=AnnotatedSqlDataSet( + data_set=input_data_set, + alias=input_data_set_alias, + _metric_time_column_name=input_data_set.column_association_for_time_dimension( + agg_time_dimension_instance.spec + ).column_name, + ), + time_spine_data_set=AnnotatedSqlDataSet( + data_set=time_spine_data_set, + alias=time_spine_data_set_alias, + _metric_time_column_name=time_spine_data_set.column_association_for_time_dimension( + agg_time_dimension_instance.spec + ).column_name, + ), ) - modified_input_instance_set = InstanceSet( - measure_instances=input_data_set.instance_set.measure_instances, - dimension_instances=input_data_set.instance_set.dimension_instances, - entity_instances=input_data_set.instance_set.entity_instances, - metric_instances=input_data_set.instance_set.metric_instances, - # we omit the metric time dimension from the right side of the self-join because we need to use - # the metric time dimension from the right side - time_dimension_instances=tuple( - [ - time_dimension_instance - for time_dimension_instance in input_data_set.instance_set.time_dimension_instances - if time_dimension_instance != agg_time_dimension_instance - ] - ), + # Remove agg_time_dimension from input data set. It will be replaced with the time spine instance. + modified_input_instance_set = input_data_set.instance_set.transform( + FilterElements(exclude_specs=InstanceSpecSet(time_dimension_specs=(agg_time_dimension_instance.spec,))) ) table_alias_to_instance_set[input_data_set_alias] = modified_input_instance_set @@ -356,7 +337,6 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat output_instance_set = ChangeAssociatedColumns(self._column_association_resolver).transform( input_data_set.instance_set ) - return SqlDataSet( instance_set=output_instance_set, sql_select_node=SqlSelectStatementNode( From a92ef2f900c445e8d228118bcad898bdbdc65415 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 16:07:38 -0700 Subject: [PATCH 03/26] Write tests for cumulative metrics queried with multiple agg time dimensions --- .../test_cumulative_metric_rendering.py | 99 ++++++++++++ ...c_with_agg_time_and_metric_time__plan0.sql | 144 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 20 +++ ...th_multiple_agg_time_dimensions__plan0.sql | 144 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 20 +++ ...multiple_metric_time_dimensions__plan0.sql | 144 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 20 +++ 7 files changed, 591 insertions(+) create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql diff --git a/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py b/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py index 954de2f9f9..17c1fd6d7f 100644 --- a/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py +++ b/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py @@ -317,3 +317,102 @@ def test_cumulative_metric_with_agg_time_dimension( sql_client=sql_client, node=dataflow_plan.sink_node, ) + + +@pytest.mark.sql_engine_snapshot +def test_cumulative_metric_with_multiple_agg_time_dimensions( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative metric queried with multiple agg time dimensions.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), + dimension_specs=(), + time_dimension_specs=( + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("revenue_instance"),), + time_granularity=TimeGranularity.DAY, + ), + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("revenue_instance"),), + time_granularity=TimeGranularity.MONTH, + ), + ), + ) + ) + + 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_cumulative_metric_with_multiple_metric_time_dimensions( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative metric queried with multiple metric time dimensions.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), + dimension_specs=(), + time_dimension_specs=(MTD_SPEC_DAY, MTD_SPEC_MONTH), + ) + ) + + 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_cumulative_metric_with_agg_time_and_metric_time( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative metric queried with one agg time dimension and one metric time dimension.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), + dimension_specs=(), + time_dimension_specs=( + MTD_SPEC_DAY, + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("revenue_instance"),), + time_granularity=TimeGranularity.MONTH, + ), + ), + ) + ) + + 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_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..8a37f21011 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,144 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - INTERVAL 2 month + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..f8a9633f89 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,20 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , subq_10.ds AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ***************************.mf_time_spine subq_10 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + ) +GROUP BY + DATE_TRUNC('month', revenue_src_28000.created_at) + , subq_10.ds diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..ebdd37074f --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,144 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + FROM ***************************.mf_time_spine subq_3 + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > subq_2.revenue_instance__ds__day - INTERVAL 2 month + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..74c750ea77 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,20 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_10.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ***************************.mf_time_spine subq_10 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + ) +GROUP BY + subq_10.ds + , DATE_TRUNC('month', revenue_src_28000.created_at) diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..e95a288987 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,144 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - INTERVAL 2 month + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..22fdb7bac8 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,20 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_10.ds AS metric_time__day + , DATE_TRUNC('month', revenue_src_28000.created_at) AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ***************************.mf_time_spine subq_10 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + ) +GROUP BY + subq_10.ds + , DATE_TRUNC('month', revenue_src_28000.created_at) From 1c0af8151d425503a21941f8791513207466363a Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 15:56:59 -0700 Subject: [PATCH 04/26] Allow multiple agg_time_dimension_specs in JoinOverTimeRangeNode --- .../dataflow/builder/dataflow_plan_builder.py | 6 +----- metricflow/dataflow/nodes/join_over_time.py | 21 ++++++++++++++----- ...indow_or_grain_with_metric_time__dfp_0.xml | 2 ++ ...t_cumulative_metric_with_window__dfp_0.xml | 3 +++ ...erived_offset_cumulative_metric__dfp_0.xml | 3 +++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/metricflow/dataflow/builder/dataflow_plan_builder.py b/metricflow/dataflow/builder/dataflow_plan_builder.py index 1177816451..9298fd8478 100644 --- a/metricflow/dataflow/builder/dataflow_plan_builder.py +++ b/metricflow/dataflow/builder/dataflow_plan_builder.py @@ -1355,13 +1355,9 @@ def _build_aggregated_measure_from_measure_source_node( # Otherwise, the measure will be aggregated over all time. time_range_node: Optional[JoinOverTimeRangeNode] = None if cumulative and queried_agg_time_dimension_specs: - # Use the time dimension spec with the smallest granularity. - agg_time_dimension_spec_for_join = sorted( - queried_agg_time_dimension_specs, key=lambda spec: spec.time_granularity.to_int() - )[0] time_range_node = JoinOverTimeRangeNode( parent_node=measure_recipe.source_node, - time_dimension_spec_for_join=agg_time_dimension_spec_for_join, + queried_agg_time_dimension_specs=tuple(queried_agg_time_dimension_specs), window=cumulative_window, grain_to_date=cumulative_grain_to_date, # Note: we use the original constraint here because the JoinOverTimeRangeNode will eventually get diff --git a/metricflow/dataflow/nodes/join_over_time.py b/metricflow/dataflow/nodes/join_over_time.py index ce77996364..bdef913556 100644 --- a/metricflow/dataflow/nodes/join_over_time.py +++ b/metricflow/dataflow/nodes/join_over_time.py @@ -19,7 +19,7 @@ class JoinOverTimeRangeNode(DataflowPlanNode): def __init__( self, parent_node: DataflowPlanNode, - time_dimension_spec_for_join: TimeDimensionSpec, + queried_agg_time_dimension_specs: Sequence[TimeDimensionSpec], window: Optional[MetricTimeWindow], grain_to_date: Optional[TimeGranularity], node_id: Optional[NodeId] = None, @@ -34,7 +34,7 @@ def __init__( (eg month to day) node_id: Override the node ID with this value time_range_constraint: time range to aggregate over - time_dimension_spec_for_join: time dimension spec to use when joining to time spine + queried_agg_time_dimension_specs: time dimension specs that will be selected from time spine table """ if window and grain_to_date: raise RuntimeError( @@ -45,7 +45,7 @@ def __init__( self._grain_to_date = grain_to_date self._window = window self.time_range_constraint = time_range_constraint - self.time_dimension_spec_for_join = time_dimension_spec_for_join + self.queried_agg_time_dimension_specs = queried_agg_time_dimension_specs # Doing a list comprehension throws a type error, so doing it this way. parent_nodes: Sequence[DataflowPlanNode] = (self._parent_node,) @@ -76,7 +76,17 @@ def window(self) -> Optional[MetricTimeWindow]: # noqa: D102 @property def displayed_properties(self) -> Sequence[DisplayedProperty]: # noqa: D102 - return super().displayed_properties + displayed_properties = tuple(super().displayed_properties) + displayed_properties += ( + DisplayedProperty("queried_agg_time_dimension_specs", self.queried_agg_time_dimension_specs), + ) + if self.window: + displayed_properties += (DisplayedProperty("window", self.window),) + if self.grain_to_date: + displayed_properties += (DisplayedProperty("grain_to_date", self.grain_to_date),) + if self.time_range_constraint: + displayed_properties += (DisplayedProperty("time_range_constraint", self.time_range_constraint),) + return displayed_properties def functionally_identical(self, other_node: DataflowPlanNode) -> bool: # noqa: D102 return ( @@ -84,6 +94,7 @@ def functionally_identical(self, other_node: DataflowPlanNode) -> bool: # noqa: and other_node.grain_to_date == self.grain_to_date and other_node.window == self.window and other_node.time_range_constraint == self.time_range_constraint + and other_node.queried_agg_time_dimension_specs == self.queried_agg_time_dimension_specs ) def with_new_parents(self, new_parent_nodes: Sequence[DataflowPlanNode]) -> JoinOverTimeRangeNode: # noqa: D102 @@ -93,5 +104,5 @@ def with_new_parents(self, new_parent_nodes: Sequence[DataflowPlanNode]) -> Join window=self.window, grain_to_date=self.grain_to_date, time_range_constraint=self.time_range_constraint, - time_dimension_spec_for_join=self.time_dimension_spec_for_join, + queried_agg_time_dimension_specs=self.queried_agg_time_dimension_specs, ) diff --git a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_no_window_or_grain_with_metric_time__dfp_0.xml b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_no_window_or_grain_with_metric_time__dfp_0.xml index 1e8d7ebb76..914569e512 100644 --- a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_no_window_or_grain_with_metric_time__dfp_0.xml +++ b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_no_window_or_grain_with_metric_time__dfp_0.xml @@ -18,6 +18,8 @@ + + diff --git a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_window__dfp_0.xml b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_window__dfp_0.xml index 96ea00a4bd..1283d92943 100644 --- a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_window__dfp_0.xml +++ b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_window__dfp_0.xml @@ -18,6 +18,9 @@ + + + diff --git a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_offset_cumulative_metric__dfp_0.xml b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_offset_cumulative_metric__dfp_0.xml index a01020b4ab..30aa24a5f4 100644 --- a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_offset_cumulative_metric__dfp_0.xml +++ b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_offset_cumulative_metric__dfp_0.xml @@ -37,6 +37,9 @@ + + + From f5acfabef89f85bc7d22e818714188ca28e0505f Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 16:14:00 -0700 Subject: [PATCH 05/26] Support for multiple queried agg time dimensions in JoinOverTimeRange SQL rendering --- metricflow/plan_conversion/dataflow_to_sql.py | 70 +++++++++++-------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 41cd70a701..ac5ad7739c 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -222,16 +222,16 @@ def _next_unique_table_alias(self) -> str: def _make_time_spine_data_set( self, - agg_time_dimension_instance: TimeDimensionInstance, + agg_time_dimension_instances: Tuple[TimeDimensionInstance, ...], time_spine_source: TimeSpineSource, time_range_constraint: Optional[TimeRangeConstraint] = None, ) -> SqlDataSet: """Make a time spine data set, which contains all date/time values like '2020-01-01', '2020-01-02'... - Returns a data set with a column for the agg_time_dimension requested. + Returns a dataset with a column selected for each agg_time_dimension requested. Column alias will use 'metric_time' or the agg_time_dimension name depending on which the user requested. """ - time_spine_instance_set = InstanceSet(time_dimension_instances=(agg_time_dimension_instance,)) + time_spine_instance_set = InstanceSet(time_dimension_instances=agg_time_dimension_instances) time_spine_table_alias = self._next_unique_table_alias() column_expr = SqlColumnReferenceExpression.from_table_and_column_names( @@ -240,22 +240,23 @@ def _make_time_spine_data_set( select_columns: Tuple[SqlSelectColumn, ...] = () apply_group_by = False - column_alias = self.column_association_resolver.resolve_spec(agg_time_dimension_instance.spec).column_name - # If the requested granularity matches that of the time spine, do a direct select. - # TODO: also handle date part. - if agg_time_dimension_instance.spec.time_granularity == time_spine_source.time_column_granularity: - select_columns += (SqlSelectColumn(expr=column_expr, column_alias=column_alias),) - # Otherwise, apply a DATE_TRUNC() and aggregate via group_by. - else: - select_columns += ( - SqlSelectColumn( - expr=SqlDateTruncExpression( - time_granularity=agg_time_dimension_instance.spec.time_granularity, arg=column_expr + for agg_time_dimension_instance in agg_time_dimension_instances: + column_alias = self.column_association_resolver.resolve_spec(agg_time_dimension_instance.spec).column_name + # If the requested granularity is the same as the granularity of the spine, do a direct select. + # TODO: also handle date part. + if agg_time_dimension_instance.spec.time_granularity == time_spine_source.time_column_granularity: + select_columns += (SqlSelectColumn(expr=column_expr, column_alias=column_alias),) + # If any columns have a different granularity, apply a DATE_TRUNC() and aggregate via group_by. + else: + select_columns += ( + SqlSelectColumn( + expr=SqlDateTruncExpression( + time_granularity=agg_time_dimension_instance.spec.time_granularity, arg=column_expr + ), + column_alias=column_alias, ), - column_alias=column_alias, - ), - ) - apply_group_by = True + ) + apply_group_by = True return SqlDataSet( instance_set=time_spine_instance_set, @@ -290,20 +291,28 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat input_data_set = node.parent_node.accept(self) input_data_set_alias = self._next_unique_table_alias() - agg_time_dimension_instance: Optional[TimeDimensionInstance] = None + # Find requested agg_time_dimensions in parent instance set. + # For now, will use instance with smallest granularity in time spine join. + # TODO: use metric's default_grain once that property is available. + agg_time_dimension_instance_for_join: Optional[TimeDimensionInstance] = None + requested_agg_time_dimension_instances: Tuple[TimeDimensionInstance, ...] = () for instance in input_data_set.instance_set.time_dimension_instances: - if instance.spec == node.time_dimension_spec_for_join: - agg_time_dimension_instance = instance - break + if instance.spec in node.queried_agg_time_dimension_specs: + requested_agg_time_dimension_instances += (instance,) + if not agg_time_dimension_instance_for_join or ( + instance.spec.time_granularity.to_int() + < agg_time_dimension_instance_for_join.spec.time_granularity.to_int() + ): + agg_time_dimension_instance_for_join = instance assert ( - agg_time_dimension_instance + agg_time_dimension_instance_for_join ), "Specified metric time spec not found in parent data set. This should have been caught by validations." time_spine_data_set_alias = self._next_unique_table_alias() - # Assemble time_spine dataset with agg_time_dimension_instance selected. + # Assemble time_spine dataset with agg_time_dimension_instance_for_join selected. time_spine_data_set = self._make_time_spine_data_set( - agg_time_dimension_instance=agg_time_dimension_instance, + agg_time_dimension_instances=requested_agg_time_dimension_instances, time_spine_source=self._time_spine_source, time_range_constraint=node.time_range_constraint, ) @@ -315,21 +324,22 @@ def visit_join_over_time_range_node(self, node: JoinOverTimeRangeNode) -> SqlDat data_set=input_data_set, alias=input_data_set_alias, _metric_time_column_name=input_data_set.column_association_for_time_dimension( - agg_time_dimension_instance.spec + agg_time_dimension_instance_for_join.spec ).column_name, ), time_spine_data_set=AnnotatedSqlDataSet( data_set=time_spine_data_set, alias=time_spine_data_set_alias, _metric_time_column_name=time_spine_data_set.column_association_for_time_dimension( - agg_time_dimension_instance.spec + agg_time_dimension_instance_for_join.spec ).column_name, ), ) - # Remove agg_time_dimension from input data set. It will be replaced with the time spine instance. + # Remove instances of agg_time_dimension from input data set. They'll be replaced with time spine instances. + agg_time_dimension_specs = tuple(dim.spec for dim in requested_agg_time_dimension_instances) modified_input_instance_set = input_data_set.instance_set.transform( - FilterElements(exclude_specs=InstanceSpecSet(time_dimension_specs=(agg_time_dimension_instance.spec,))) + FilterElements(exclude_specs=InstanceSpecSet(time_dimension_specs=agg_time_dimension_specs)) ) table_alias_to_instance_set[input_data_set_alias] = modified_input_instance_set @@ -1222,7 +1232,7 @@ def visit_join_to_time_spine_node(self, node: JoinToTimeSpineNode) -> SqlDataSet # Build time spine data set using the requested agg_time_dimension name. time_spine_alias = self._next_unique_table_alias() time_spine_dataset = self._make_time_spine_data_set( - agg_time_dimension_instance=agg_time_dimension_instance_for_join, + agg_time_dimension_instances=(agg_time_dimension_instance_for_join,), time_spine_source=self._time_spine_source, time_range_constraint=node.time_range_constraint, ) From 8bdb7d9653b5add3426306fc12f1ac7d83ba0e75 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 16:10:39 -0700 Subject: [PATCH 06/26] Update snapshots to reflect code changes --- ...c_with_agg_time_and_metric_time__plan0.sql | 10 +++++--- ..._time_and_metric_time__plan0_optimized.sql | 23 +++++++++++++------ ...th_multiple_agg_time_dimensions__plan0.sql | 6 ++++- ...e_agg_time_dimensions__plan0_optimized.sql | 23 +++++++++++++------ ...multiple_metric_time_dimensions__plan0.sql | 6 ++++- ...etric_time_dimensions__plan0_optimized.sql | 23 +++++++++++++------ 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql index 8a37f21011..78a6550fbd 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -18,7 +18,8 @@ FROM ( FROM ( -- Join Self Over Time Range SELECT - subq_2.metric_time__day AS metric_time__day + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day , subq_1.ds__day AS ds__day , subq_1.ds__week AS ds__week , subq_1.ds__month AS ds__month @@ -32,7 +33,6 @@ FROM ( , subq_1.ds__extract_doy AS ds__extract_doy , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week - , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year @@ -57,8 +57,12 @@ FROM ( FROM ( -- Time Spine SELECT - subq_3.ds AS metric_time__day + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds ) subq_2 INNER JOIN ( -- Metric Time Dimension 'ds' diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql index f8a9633f89..eaaba26ba2 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -3,18 +3,27 @@ -- Aggregate Measures -- Compute Metrics via Expressions SELECT - DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month - , subq_10.ds AS metric_time__day + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue -FROM ***************************.mf_time_spine subq_10 +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 INNER JOIN ***************************.fct_revenue revenue_src_28000 ON ( - DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day ) AND ( - DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.metric_time__day - INTERVAL 2 month ) GROUP BY - DATE_TRUNC('month', revenue_src_28000.created_at) - , subq_10.ds + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql index ebdd37074f..08079e14cc 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -19,6 +19,7 @@ FROM ( -- Join Self Over Time Range SELECT subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month , subq_1.ds__day AS ds__day , subq_1.ds__week AS ds__week , subq_1.ds__month AS ds__month @@ -31,7 +32,6 @@ FROM ( , subq_1.ds__extract_dow AS ds__extract_dow , subq_1.ds__extract_doy AS ds__extract_doy , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week - , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year @@ -58,7 +58,11 @@ FROM ( -- Time Spine SELECT subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) ) subq_2 INNER JOIN ( -- Metric Time Dimension 'ds' diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql index 74c750ea77..df79dc0757 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -3,18 +3,27 @@ -- Aggregate Measures -- Compute Metrics via Expressions SELECT - subq_10.ds AS revenue_instance__ds__day - , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue -FROM ***************************.mf_time_spine subq_10 +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 INNER JOIN ***************************.fct_revenue revenue_src_28000 ON ( - DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day ) AND ( - DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.revenue_instance__ds__day - INTERVAL 2 month ) GROUP BY - subq_10.ds - , DATE_TRUNC('month', revenue_src_28000.created_at) + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql index e95a288987..ec77b12959 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -19,6 +19,7 @@ FROM ( -- Join Self Over Time Range SELECT subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month , subq_1.ds__day AS ds__day , subq_1.ds__week AS ds__week , subq_1.ds__month AS ds__month @@ -42,7 +43,6 @@ FROM ( , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy , subq_1.metric_time__week AS metric_time__week - , subq_1.metric_time__month AS metric_time__month , subq_1.metric_time__quarter AS metric_time__quarter , subq_1.metric_time__year AS metric_time__year , subq_1.metric_time__extract_year AS metric_time__extract_year @@ -58,7 +58,11 @@ FROM ( -- Time Spine SELECT subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) ) subq_2 INNER JOIN ( -- Metric Time Dimension 'ds' diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql index 22fdb7bac8..5a4fb59200 100644 --- a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -3,18 +3,27 @@ -- Aggregate Measures -- Compute Metrics via Expressions SELECT - subq_10.ds AS metric_time__day - , DATE_TRUNC('month', revenue_src_28000.created_at) AS metric_time__month + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue -FROM ***************************.mf_time_spine subq_10 +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 INNER JOIN ***************************.fct_revenue revenue_src_28000 ON ( - DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_10.ds + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day ) AND ( - DATE_TRUNC('day', revenue_src_28000.created_at) > subq_10.ds - INTERVAL 2 month + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.metric_time__day - INTERVAL 2 month ) GROUP BY - subq_10.ds - , DATE_TRUNC('month', revenue_src_28000.created_at) + subq_9.metric_time__day + , subq_9.metric_time__month From 946cbae5cd8028189ce7089c427070420681bc8e Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 16:16:12 -0700 Subject: [PATCH 07/26] Changelog --- .changes/unreleased/Fixes-20240612-161605.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/Fixes-20240612-161605.yaml diff --git a/.changes/unreleased/Fixes-20240612-161605.yaml b/.changes/unreleased/Fixes-20240612-161605.yaml new file mode 100644 index 0000000000..7800c5f9a9 --- /dev/null +++ b/.changes/unreleased/Fixes-20240612-161605.yaml @@ -0,0 +1,7 @@ +kind: Fixes +body: When querying multiple agg time or metric time dimensions with a cumulative + metric, select all of them from the time spine table. +time: 2024-06-12T16:16:05.678697-07:00 +custom: + Author: courtneyholcomb + Issue: "1271" From 317e64b1192bfc0518e053ad492b961c23cc20ba Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 12 Jun 2024 17:20:25 -0700 Subject: [PATCH 08/26] Update SQL engine snapshots --- ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ ...c_with_agg_time_and_metric_time__plan0.sql | 148 ++++++++++++++++++ ..._time_and_metric_time__plan0_optimized.sql | 29 ++++ ...th_multiple_agg_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...e_agg_time_dimensions__plan0_optimized.sql | 29 ++++ ...multiple_metric_time_dimensions__plan0.sql | 148 ++++++++++++++++++ ...etric_time_dimensions__plan0_optimized.sql | 29 ++++ 36 files changed, 3186 insertions(+) create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..83ccdafc37 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(subq_3.ds, month) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + revenue_instance__ds__month + , metric_time__day + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_SUB(CAST(subq_2.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + ) subq_4 + ) subq_5 + GROUP BY + revenue_instance__ds__month + , metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..35a428887f --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(ds, month) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + revenue_instance__ds__month + , metric_time__day +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_9.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) > DATE_SUB(CAST(subq_9.metric_time__day AS DATETIME), INTERVAL 2 month) + ) +GROUP BY + revenue_instance__ds__month + , metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..c068c9dc98 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATETIME_TRUNC(subq_3.ds, month) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + revenue_instance__ds__day + , revenue_instance__ds__month + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > DATE_SUB(CAST(subq_2.revenue_instance__ds__day AS DATETIME), INTERVAL 2 month) + ) + ) subq_4 + ) subq_5 + GROUP BY + revenue_instance__ds__day + , revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..890e5a2d78 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATETIME_TRUNC(ds, month) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + revenue_instance__ds__day + , revenue_instance__ds__month +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_9.revenue_instance__ds__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) > DATE_SUB(CAST(subq_9.revenue_instance__ds__day AS DATETIME), INTERVAL 2 month) + ) +GROUP BY + revenue_instance__ds__day + , revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..caddda4623 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, month) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__month + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_SUB(CAST(subq_2.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..bfbdc21801 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, month) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + metric_time__day + , metric_time__month +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_9.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) > DATE_SUB(CAST(subq_9.metric_time__day AS DATETIME), INTERVAL 2 month) + ) +GROUP BY + metric_time__day + , metric_time__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..22de7b52c0 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..af273a6d27 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..abb3344a26 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > DATEADD(month, -2, subq_2.revenue_instance__ds__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..6caf616294 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.revenue_instance__ds__day) + ) +GROUP BY + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..48ebb94d10 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..793cd64067 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.metric_time__day + , subq_9.metric_time__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..203f1ddd3d --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - MAKE_INTERVAL(months => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..f00cf20a1b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.metric_time__day - MAKE_INTERVAL(months => 2) + ) +GROUP BY + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..443cc1255e --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > subq_2.revenue_instance__ds__day - MAKE_INTERVAL(months => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..fb051bf687 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.revenue_instance__ds__day - MAKE_INTERVAL(months => 2) + ) +GROUP BY + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..aafb23085c --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - MAKE_INTERVAL(months => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..95a3491e9a --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_9.metric_time__day - MAKE_INTERVAL(months => 2) + ) +GROUP BY + subq_9.metric_time__day + , subq_9.metric_time__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..b6b4ae0325 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..af273a6d27 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..7bd3132dc3 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > DATEADD(month, -2, subq_2.revenue_instance__ds__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..6caf616294 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.revenue_instance__ds__day) + ) +GROUP BY + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..1d665cb206 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..793cd64067 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.metric_time__day + , subq_9.metric_time__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..291d204d49 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..af273a6d27 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..bbb80a8f2c --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > DATEADD(month, -2, subq_2.revenue_instance__ds__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..6caf616294 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.revenue_instance__ds__day) + ) +GROUP BY + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..9ea017acab --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..793cd64067 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.metric_time__day + , subq_9.metric_time__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql new file mode 100644 index 0000000000..273e14d03f --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__month + , subq_6.metric_time__day + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__month + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_ADD('month', -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__month + , subq_5.metric_time__day +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql new file mode 100644 index 0000000000..251cdb4cb8 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_agg_time_and_metric_time__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_9.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS revenue_instance__ds__month + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_10 + GROUP BY + DATE_TRUNC('month', ds) + , ds +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATE_ADD('month', -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.revenue_instance__ds__month + , subq_9.metric_time__day diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql new file mode 100644 index 0000000000..6c3054ee99 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.revenue_instance__ds__day + , subq_6.revenue_instance__ds__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] + SELECT + subq_4.revenue_instance__ds__day + , subq_4.revenue_instance__ds__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_2.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__day AS metric_time__day + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS revenue_instance__ds__day + , DATE_TRUNC('month', subq_3.ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.revenue_instance__ds__day <= subq_2.revenue_instance__ds__day + ) AND ( + subq_1.revenue_instance__ds__day > DATE_ADD('month', -2, subq_2.revenue_instance__ds__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__day + , subq_5.revenue_instance__ds__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..6072af4f6d --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_agg_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__day', 'revenue_instance__ds__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_9.revenue_instance__ds__month AS revenue_instance__ds__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS revenue_instance__ds__day + , DATE_TRUNC('month', ds) AS revenue_instance__ds__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.revenue_instance__ds__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATE_ADD('month', -2, subq_9.revenue_instance__ds__day) + ) +GROUP BY + subq_9.revenue_instance__ds__day + , subq_9.revenue_instance__ds__month diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql new file mode 100644 index 0000000000..4ab76dcbe5 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0.sql @@ -0,0 +1,148 @@ +-- Compute Metrics via Expressions +SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS trailing_2_months_revenue +FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_ADD('month', -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month +) subq_6 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql new file mode 100644 index 0000000000..a2359e82ea --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_multiple_metric_time_dimensions__plan0_optimized.sql @@ -0,0 +1,29 @@ +-- Join Self Over Time Range +-- Pass Only Elements: ['txn_revenue', 'metric_time__day', 'metric_time__month'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__day AS metric_time__day + , subq_9.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue +FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_10 + GROUP BY + ds + , DATE_TRUNC('month', ds) +) subq_9 +INNER JOIN + ***************************.fct_revenue revenue_src_28000 +ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_9.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATE_ADD('month', -2, subq_9.metric_time__day) + ) +GROUP BY + subq_9.metric_time__day + , subq_9.metric_time__month From 0cf0f7a8a2233542afb0411ba1d02dcf4f4fbb9a Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 14:31:03 -0700 Subject: [PATCH 09/26] Add requires_ordering property to SqlWindowFunction --- metricflow/sql/sql_exprs.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/metricflow/sql/sql_exprs.py b/metricflow/sql/sql_exprs.py index 3a1f424822..0a62e9d3d2 100644 --- a/metricflow/sql/sql_exprs.py +++ b/metricflow/sql/sql_exprs.py @@ -952,6 +952,16 @@ class SqlWindowFunction(Enum): LAST_VALUE = "LAST_VALUE" AVERAGE = "AVG" + @property + def requires_ordering(self) -> bool: + """Asserts whether or not ordering the window function will have an impact on the resulting value.""" + if self is SqlWindowFunction.FIRST_VALUE or self is SqlWindowFunction.LAST_VALUE: + return True + elif self is SqlWindowFunction.AVERAGE: + return False + else: + assert_values_exhausted(self) + @dataclass(frozen=True) class SqlWindowOrderByArgument: From bc3f0d36d74f96578b34f9a16833094e790a8567 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 16:01:16 -0700 Subject: [PATCH 10/26] Add WindowReaggregationNode --- .../metricflow_semantics/dag/id_prefix.py | 1 + .../nodes/window_reaggregation_node.py | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 metricflow/dataflow/nodes/window_reaggregation_node.py diff --git a/metricflow-semantics/metricflow_semantics/dag/id_prefix.py b/metricflow-semantics/metricflow_semantics/dag/id_prefix.py index 7de99f3767..49c5993ded 100644 --- a/metricflow-semantics/metricflow_semantics/dag/id_prefix.py +++ b/metricflow-semantics/metricflow_semantics/dag/id_prefix.py @@ -53,6 +53,7 @@ class StaticIdPrefix(IdPrefix, Enum, metaclass=EnumMetaClassHelper): DATAFLOW_NODE_MIN_MAX_ID_PREFIX = "mm" DATAFLOW_NODE_ADD_UUID_COLUMN_PREFIX = "auid" DATAFLOW_NODE_JOIN_CONVERSION_EVENTS_PREFIX = "jce" + DATAFLOW_NODE_WINDOW_REAGGREGATION_ID_PREFIX = "wr" SQL_EXPR_COLUMN_REFERENCE_ID_PREFIX = "cr" SQL_EXPR_COMPARISON_ID_PREFIX = "cmp" diff --git a/metricflow/dataflow/nodes/window_reaggregation_node.py b/metricflow/dataflow/nodes/window_reaggregation_node.py new file mode 100644 index 0000000000..a8a0b8523d --- /dev/null +++ b/metricflow/dataflow/nodes/window_reaggregation_node.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +from typing import Sequence, Set + +from metricflow_semantics.dag.id_prefix import IdPrefix, StaticIdPrefix +from metricflow_semantics.dag.mf_dag import DisplayedProperty +from metricflow_semantics.specs.spec_classes import LinkableInstanceSpec, MetricSpec, TimeDimensionSpec +from metricflow_semantics.visitor import VisitorOutputT + +from metricflow.dataflow.dataflow_plan import ( + DataflowPlanNode, + DataflowPlanNodeVisitor, +) +from metricflow.dataflow.nodes.compute_metrics import ComputeMetricsNode + + +class WindowReaggregationNode(DataflowPlanNode): + """A node that re-aggregates metrics using window functions. + + Currently used for calculating cumulative metrics at various granularities. + """ + + def __init__( # noqa: D107 + self, + parent_node: ComputeMetricsNode, + metric_spec: MetricSpec, + order_by_spec: TimeDimensionSpec, + partition_by_specs: Sequence[TimeDimensionSpec], + ) -> None: + if order_by_spec in partition_by_specs: + raise ValueError( + "Order by spec found in parition by specs for WindowAggregationNode. This indicates internal misconfiguration" + f" because reaggregation should not be needed in this circumstance. Order by spec: {order_by_spec}; " + f"Partition by specs:{partition_by_specs}" + ) + + self.parent_node = parent_node + self.metric_spec = metric_spec + self.order_by_spec = order_by_spec + self.partition_by_specs = partition_by_specs + + super().__init__(node_id=self.create_unique_id(), parent_nodes=(self.parent_node,)) + + @classmethod + def id_prefix(cls) -> IdPrefix: # noqa: D102 + return StaticIdPrefix.DATAFLOW_NODE_WINDOW_REAGGREGATION_ID_PREFIX + + def accept(self, visitor: DataflowPlanNodeVisitor[VisitorOutputT]) -> VisitorOutputT: # noqa: D102 + return visitor.visit_window_reaggregation_node(self) + + @property + def description(self) -> str: # noqa: D102 + return """Re-aggregate Metrics via Window Functions""" + + @property + def displayed_properties(self) -> Sequence[DisplayedProperty]: # noqa: D102 + return tuple(super().displayed_properties) + ( + DisplayedProperty("metric_spec", self.metric_spec), + DisplayedProperty("order_by_spec", self.order_by_spec), + DisplayedProperty("partition_by_specs", self.partition_by_specs), + ) + + def functionally_identical(self, other_node: DataflowPlanNode) -> bool: # noqa: D102 + return ( + isinstance(other_node, self.__class__) + and other_node.parent_node == self.parent_node + and other_node.metric_spec == self.metric_spec + and other_node.order_by_spec == self.order_by_spec + and other_node.partition_by_specs == self.partition_by_specs + ) + + def with_new_parents(self, new_parent_nodes: Sequence[DataflowPlanNode]) -> WindowReaggregationNode: # noqa: D102 + assert len(new_parent_nodes) == 1 + new_parent_node = new_parent_nodes[0] + assert isinstance( + new_parent_node, ComputeMetricsNode + ), "WindowReaggregationNode can only have ComputeMetricsNode as parent node." + return WindowReaggregationNode( + parent_node=new_parent_node, + metric_spec=self.metric_spec, + order_by_spec=self.order_by_spec, + partition_by_specs=self.partition_by_specs, + ) + + @property + def aggregated_to_elements(self) -> Set[LinkableInstanceSpec]: # noqa: D102 + return set() From 1500f9aa5b481c18a262f764b7337032b89674c7 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 16:01:38 -0700 Subject: [PATCH 11/26] Visitor methods for WindowReaggregation node - primarily SQL rendering logic --- .../metricflow_semantics/instances.py | 12 +++ metricflow/dataflow/dataflow_plan.py | 5 + .../source_scan/cm_branch_combiner.py | 25 +++-- .../source_scan/source_scan_optimizer.py | 5 + metricflow/execution/dataflow_to_execution.py | 5 + metricflow/plan_conversion/dataflow_to_sql.py | 99 ++++++++++++++++++- .../source_scan/test_source_scan_optimizer.py | 4 + 7 files changed, 144 insertions(+), 11 deletions(-) diff --git a/metricflow-semantics/metricflow_semantics/instances.py b/metricflow-semantics/metricflow_semantics/instances.py index 1ee3cd90f3..3b64d90743 100644 --- a/metricflow-semantics/metricflow_semantics/instances.py +++ b/metricflow-semantics/metricflow_semantics/instances.py @@ -216,3 +216,15 @@ def spec_set(self) -> InstanceSpecSet: # noqa: D102 metric_specs=tuple(x.spec for x in self.metric_instances), metadata_specs=tuple(x.spec for x in self.metadata_instances), ) + + @property + def as_tuple(self) -> Tuple[MdoInstance, ...]: # noqa: D102 + return ( + self.measure_instances + + self.dimension_instances + + self.time_dimension_instances + + self.entity_instances + + self.group_by_metric_instances + + self.metric_instances + + self.metadata_instances + ) diff --git a/metricflow/dataflow/dataflow_plan.py b/metricflow/dataflow/dataflow_plan.py index ecf2fc427b..8b113a5de8 100644 --- a/metricflow/dataflow/dataflow_plan.py +++ b/metricflow/dataflow/dataflow_plan.py @@ -32,6 +32,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode + from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode @@ -137,6 +138,10 @@ def visit_aggregate_measures_node(self, node: AggregateMeasuresNode) -> VisitorO def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> VisitorOutputT: # noqa: D102 pass + @abstractmethod + def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> VisitorOutputT: # noqa: D102 + pass + @abstractmethod def visit_order_by_limit_node(self, node: OrderByLimitNode) -> VisitorOutputT: # noqa: D102 pass diff --git a/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py b/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py index 5d18f3121c..1124f00498 100644 --- a/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py +++ b/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py @@ -26,6 +26,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.dataflow.optimizer.source_scan.matching_linkable_specs import MatchingLinkableSpecsTransform @@ -327,13 +328,19 @@ def _handle_unsupported_node(self, current_right_node: DataflowPlanNode) -> Comp ) return ComputeMetricsBranchCombinerResult() + def visit_window_reaggregation_node( # noqa: D102 + self, node: WindowReaggregationNode + ) -> ComputeMetricsBranchCombinerResult: + self._log_visit_node_type(node) + return self._handle_unsupported_node(node) + def visit_order_by_limit_node(self, node: OrderByLimitNode) -> ComputeMetricsBranchCombinerResult: # noqa: D102 self._log_visit_node_type(node) return self._handle_unsupported_node(node) def visit_where_constraint_node( # noqa: D102 self, node: WhereConstraintNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) @@ -345,13 +352,11 @@ def visit_write_to_result_data_table_node( # noqa: D102 def visit_write_to_result_table_node( # noqa: D102 self, node: WriteToResultTableNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._handle_unsupported_node(node) - def visit_filter_elements_node( # noqa: D102 - self, node: FilterElementsNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + def visit_filter_elements_node(self, node: FilterElementsNode) -> ComputeMetricsBranchCombinerResult: # noqa: D102 self._log_visit_node_type(node) current_right_node = node @@ -403,19 +408,19 @@ def visit_combine_aggregated_outputs_node( # noqa: D102 def visit_constrain_time_range_node( # noqa: D102 self, node: ConstrainTimeRangeNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) def visit_join_over_time_range_node( # noqa: D102 self, node: JoinOverTimeRangeNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) def visit_semi_additive_join_node( # noqa: D102 self, node: SemiAdditiveJoinNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) @@ -427,7 +432,7 @@ def visit_metric_time_dimension_transform_node( # noqa: D102 def visit_join_to_time_spine_node( # noqa: D102 self, node: JoinToTimeSpineNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) @@ -439,7 +444,7 @@ def visit_add_generated_uuid_column_node( # noqa: D102 def visit_join_conversion_events_node( # noqa: D102 self, node: JoinConversionEventsNode - ) -> ComputeMetricsBranchCombinerResult: # noqa: D102 + ) -> ComputeMetricsBranchCombinerResult: self._log_visit_node_type(node) return self._default_handler(node) diff --git a/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py b/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py index 1fd708da21..e7f87aa992 100644 --- a/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py +++ b/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py @@ -28,6 +28,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.dataflow.optimizer.dataflow_plan_optimizer import DataflowPlanOptimizer @@ -137,6 +138,10 @@ def visit_aggregate_measures_node(self, node: AggregateMeasuresNode) -> Optimize self._log_visit_node_type(node) return self._default_base_output_handler(node) + def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> OptimizeBranchResult: # noqa: D102 + self._log_visit_node_type(node) + return self._default_base_output_handler(node) + def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> OptimizeBranchResult: # noqa: D102 self._log_visit_node_type(node) # Run the optimizer on the parent branch to handle derived metrics, which are defined recursively in the DAG. diff --git a/metricflow/execution/dataflow_to_execution.py b/metricflow/execution/dataflow_to_execution.py index fa0b7ccbbf..b553590465 100644 --- a/metricflow/execution/dataflow_to_execution.py +++ b/metricflow/execution/dataflow_to_execution.py @@ -25,6 +25,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.execution.convert_to_execution_plan import ConvertToExecutionPlanResult @@ -133,6 +134,10 @@ def visit_aggregate_measures_node(self, node: AggregateMeasuresNode) -> ConvertT def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> ConvertToExecutionPlanResult: raise NotImplementedError + @override + def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> ConvertToExecutionPlanResult: + raise NotImplementedError + @override def visit_order_by_limit_node(self, node: OrderByLimitNode) -> ConvertToExecutionPlanResult: raise NotImplementedError diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index ac5ad7739c..edde71b43e 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -2,7 +2,7 @@ import logging from collections import OrderedDict -from typing import List, Optional, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Set, Tuple, Union from dbt_semantic_interfaces.enum_extension import assert_values_exhausted from dbt_semantic_interfaces.naming.keywords import METRIC_TIME_ELEMENT_NAME @@ -19,6 +19,7 @@ from metricflow_semantics.instances import ( GroupByMetricInstance, InstanceSet, + MdoInstance, MetadataInstance, MetricInstance, TimeDimensionInstance, @@ -31,6 +32,7 @@ ) from metricflow_semantics.specs.spec_classes import ( GroupByMetricSpec, + InstanceSpec, MeasureSpec, MetadataSpec, MetricSpec, @@ -60,6 +62,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.dataset.dataset_classes import DataSet @@ -1610,3 +1613,97 @@ def visit_join_conversion_events_node(self, node: JoinConversionEventsNode) -> S from_source_alias=output_data_set_alias, ), ) + + def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> SqlDataSet: # noqa: D102 + from_data_set = node.parent_node.accept(self) + parent_instance_set = from_data_set.instance_set # remove order by col + parent_data_set_alias = self._next_unique_table_alias() + + metric_instance = None + order_by_instance = None + partition_by_instances: Tuple[MdoInstance, ...] = () + for instance in parent_instance_set.as_tuple: + if instance.spec == node.metric_spec: + metric_instance = instance + continue + if instance.spec == node.order_by_spec: + order_by_instance = instance + if instance.spec in node.partition_by_specs: + partition_by_instances += (instance,) + expected_specs: Set[InstanceSpec] = {node.metric_spec, node.order_by_spec}.union(node.partition_by_specs) + assert metric_instance and order_by_instance and partition_by_instances, ( + "Did not receive appropriate instances to render SQL for WindowReaggregationNode. Expected instances matching " + f"specs: {expected_specs}. Got: {parent_instance_set.as_tuple}." + ) + + # Pending DSI upgrade: + # sql_window_function = SqlWindowFunction[ + # self._metric_lookup.get_metric( + # metric_instance.spec.reference + # ).type_params.cumulative_type_params.period_agg.name + # ] + sql_window_function = SqlWindowFunction.FIRST_VALUE # placeholder for now + order_by_args = [] + if sql_window_function.requires_ordering: + order_by_args.append( + SqlWindowOrderByArgument( + expr=SqlColumnReferenceExpression.from_table_and_column_names( + table_alias=parent_data_set_alias, + column_name=order_by_instance.associated_column.column_name, + ), + ) + ) + metric_select_column = SqlSelectColumn( + expr=SqlWindowFunctionExpression( + sql_function=sql_window_function, + sql_function_args=[ + SqlColumnReferenceExpression.from_table_and_column_names( + table_alias=parent_data_set_alias, column_name=metric_instance.associated_column.column_name + ) + ], + partition_by_args=[ + SqlColumnReferenceExpression.from_table_and_column_names( + table_alias=parent_data_set_alias, + column_name=partition_by_instance.associated_column.column_name, + ) + for partition_by_instance in partition_by_instances + ], + order_by_args=order_by_args, + ), + column_alias=metric_instance.associated_column.column_name, + ) + + # Order by instance should not be included in the output dataset because it was not requested in the query. + output_instance_set = parent_instance_set.transform( + FilterElements(exclude_specs=InstanceSpecSet(time_dimension_specs=(order_by_instance.spec,))) + ) + + # Can't include window function in a group by, so we use a subquery and apply group by in the outer query. + subquery_select_columns = output_instance_set.transform( + FilterElements(exclude_specs=InstanceSpecSet(metric_specs=(metric_instance.spec,))) + ).transform( + CreateSelectColumnsForInstances(parent_data_set_alias, self._column_association_resolver) + ).as_tuple() + ( + metric_select_column, + ) + subquery = SqlSelectStatementNode( + description="", # description included in outer query + select_columns=subquery_select_columns, + from_source=from_data_set.checked_sql_select_node, + from_source_alias=parent_data_set_alias, + ) + subquery_alias = self._next_unique_table_alias() + + outer_query_select_columns = output_instance_set.transform( + CreateSelectColumnsForInstances(subquery_alias, self._column_association_resolver) + ).as_tuple() + return SqlDataSet( + instance_set=output_instance_set, + sql_select_node=SqlSelectStatementNode( + description=node.description, + select_columns=outer_query_select_columns, + from_source=subquery, + from_source_alias=subquery_alias, + group_bys=outer_query_select_columns, + ), + ) diff --git a/tests_metricflow/dataflow/optimizer/source_scan/test_source_scan_optimizer.py b/tests_metricflow/dataflow/optimizer/source_scan/test_source_scan_optimizer.py index dba5380f04..f6e10745dd 100644 --- a/tests_metricflow/dataflow/optimizer/source_scan/test_source_scan_optimizer.py +++ b/tests_metricflow/dataflow/optimizer/source_scan/test_source_scan_optimizer.py @@ -39,6 +39,7 @@ from metricflow.dataflow.nodes.read_sql_source import ReadSqlSourceNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.dataflow.optimizer.source_scan.source_scan_optimizer import SourceScanOptimizer @@ -66,6 +67,9 @@ def visit_aggregate_measures_node(self, node: AggregateMeasuresNode) -> int: # def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> int: # noqa: D102 return self._sum_parents(node) + def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> int: # noqa: D102 + return self._sum_parents(node) + def visit_order_by_limit_node(self, node: OrderByLimitNode) -> int: # noqa: D102 return self._sum_parents(node) From dcae9f41a6158c451f2c8887a6e8d24af1de2f4d Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 16:08:04 -0700 Subject: [PATCH 12/26] Changelog --- .changes/unreleased/Features-20240613-160758.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/Features-20240613-160758.yaml diff --git a/.changes/unreleased/Features-20240613-160758.yaml b/.changes/unreleased/Features-20240613-160758.yaml new file mode 100644 index 0000000000..ac7fe2dfbf --- /dev/null +++ b/.changes/unreleased/Features-20240613-160758.yaml @@ -0,0 +1,7 @@ +kind: Features +body: Adds a new dataflow plan node to re-aggregate metrics using window functions. + Needed to calculate cumulative metrics at non-default granularities. +time: 2024-06-13T16:07:58.767447-07:00 +custom: + Author: courtneyholcomb + Issue: "1274" From f3d478e401cf0ad25bb3409d924295c8f1472845 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 16:14:12 -0700 Subject: [PATCH 13/26] Only render SelectStatementNode description if it's not an empty string Needed now that there might be an empty string from the subquery in WindowAggregationNode. --- metricflow/sql/render/sql_plan_renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricflow/sql/render/sql_plan_renderer.py b/metricflow/sql/render/sql_plan_renderer.py index 6ee1d34d07..99f4286ab0 100644 --- a/metricflow/sql/render/sql_plan_renderer.py +++ b/metricflow/sql/render/sql_plan_renderer.py @@ -229,7 +229,7 @@ def visit_select_statement_node(self, node: SqlSelectStatementNode) -> SqlPlanRe combined_params = SqlBindParameters() # Render description section - description_section = "\n".join([f"-- {x}" for x in node.description.split("\n")]) + description_section = "\n".join([f"-- {x}" for x in node.description.split("\n") if x]) # Render "SELECT" column section select_section, select_params = self._render_select_columns_section( From 57e546408e5bde3b72b737d5c6613a6831a4880d Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 16:33:29 -0700 Subject: [PATCH 14/26] Don't optimize subqueries if it will put a window function into the group by --- .../optimizer/rewriting_sub_query_reducer.py | 30 +++++++++++++++++++ metricflow/sql/sql_exprs.py | 9 ++++++ 2 files changed, 39 insertions(+) diff --git a/metricflow/sql/optimizer/rewriting_sub_query_reducer.py b/metricflow/sql/optimizer/rewriting_sub_query_reducer.py index 5f14734b4c..5d1eb7b6a5 100644 --- a/metricflow/sql/optimizer/rewriting_sub_query_reducer.py +++ b/metricflow/sql/optimizer/rewriting_sub_query_reducer.py @@ -138,6 +138,10 @@ def _select_columns_are_column_references(select_columns: Tuple[SqlSelectColumn, return False return True + @staticmethod + def _select_columns_with_window_functions(select_columns: Tuple[SqlSelectColumn, ...]) -> List[SqlSelectColumn]: + return [select_column for select_column in select_columns if select_column.expr.as_window_function_expression] + @staticmethod def _select_column_for_alias(column_alias: str, select_columns: Sequence[SqlSelectColumn]) -> SqlSelectColumn: for select_column in select_columns: @@ -276,6 +280,32 @@ def _current_node_can_be_reduced(self, node: SqlSelectStatementNode) -> bool: ) > 0 and not SqlRewritingSubQueryReducerVisitor._select_columns_are_column_references(node.select_columns): return False + # If the group by is referencing a window function in the parent node, it can't be reduced. + # Window functions can't be included in group by. + parent_column_aliases_with_window_functions = { + select_column.column_alias + for select_column in SqlRewritingSubQueryReducerVisitor._select_columns_with_window_functions( + parent_select_node.select_columns + ) + } + if len(node.group_bys) > 0 and [ + group_by + for group_by in node.group_bys + if ( + group_by.column_alias in parent_column_aliases_with_window_functions + or ( + group_by.expr.as_column_reference_expression + and group_by.expr.as_column_reference_expression.col_ref.column_name + in parent_column_aliases_with_window_functions + ) + or ( + group_by.expr.as_string_expression + and group_by.expr.as_string_expression.sql_expr in parent_column_aliases_with_window_functions + ) + ) + ]: + return False + # If the parent select node contains string columns, and this has a GROUP BY, don't reduce as string columns # can have special meanings in a GROUP BY. For example, # diff --git a/metricflow/sql/sql_exprs.py b/metricflow/sql/sql_exprs.py index 0a62e9d3d2..3e7d857f5a 100644 --- a/metricflow/sql/sql_exprs.py +++ b/metricflow/sql/sql_exprs.py @@ -70,6 +70,11 @@ def as_string_expression(self) -> Optional[SqlStringExpression]: """If this is a string expression, return self.""" return None + @property + def as_window_function_expression(self) -> Optional[SqlWindowFunctionExpression]: + """If this is a window function expression, return self.""" + return None + @abstractmethod def rewrite( self, @@ -1092,6 +1097,10 @@ def lineage(self) -> SqlExpressionTreeLineage: # noqa: D102 tuple(x.lineage for x in self.parent_nodes) + (SqlExpressionTreeLineage(function_exprs=(self,)),) ) + @property + def as_window_function_expression(self) -> Optional[SqlWindowFunctionExpression]: # noqa: D102 + return self + def matches(self, other: SqlExpressionNode) -> bool: # noqa: D102 if not isinstance(other, SqlWindowFunctionExpression): return False From 7a250470c8ac0b0c9380bcc37e0a9c2351d9c0f6 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 17:19:20 -0700 Subject: [PATCH 15/26] Fix type for WindowReaggregationNode.partition_by_specs --- metricflow/dataflow/nodes/window_reaggregation_node.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/metricflow/dataflow/nodes/window_reaggregation_node.py b/metricflow/dataflow/nodes/window_reaggregation_node.py index a8a0b8523d..cd28af7908 100644 --- a/metricflow/dataflow/nodes/window_reaggregation_node.py +++ b/metricflow/dataflow/nodes/window_reaggregation_node.py @@ -4,13 +4,10 @@ from metricflow_semantics.dag.id_prefix import IdPrefix, StaticIdPrefix from metricflow_semantics.dag.mf_dag import DisplayedProperty -from metricflow_semantics.specs.spec_classes import LinkableInstanceSpec, MetricSpec, TimeDimensionSpec +from metricflow_semantics.specs.spec_classes import InstanceSpec, LinkableInstanceSpec, MetricSpec, TimeDimensionSpec from metricflow_semantics.visitor import VisitorOutputT -from metricflow.dataflow.dataflow_plan import ( - DataflowPlanNode, - DataflowPlanNodeVisitor, -) +from metricflow.dataflow.dataflow_plan import DataflowPlanNode, DataflowPlanNodeVisitor from metricflow.dataflow.nodes.compute_metrics import ComputeMetricsNode @@ -25,7 +22,7 @@ def __init__( # noqa: D107 parent_node: ComputeMetricsNode, metric_spec: MetricSpec, order_by_spec: TimeDimensionSpec, - partition_by_specs: Sequence[TimeDimensionSpec], + partition_by_specs: Sequence[InstanceSpec], ) -> None: if order_by_spec in partition_by_specs: raise ValueError( From 22d9c0690b2f862034a1d056132bcd401f7c00c4 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 17:20:33 -0700 Subject: [PATCH 16/26] Helpers to get min queryable granularity for metric --- .../model/semantics/metric_lookup.py | 24 +++++++++++++++++++ .../model/semantics/semantic_model_lookup.py | 19 ++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/metricflow-semantics/metricflow_semantics/model/semantics/metric_lookup.py b/metricflow-semantics/metricflow_semantics/model/semantics/metric_lookup.py index ca2b01eadb..21e5fb8ac1 100644 --- a/metricflow-semantics/metricflow_semantics/model/semantics/metric_lookup.py +++ b/metricflow-semantics/metricflow_semantics/model/semantics/metric_lookup.py @@ -9,6 +9,7 @@ from dbt_semantic_interfaces.protocols.metric import Metric, MetricInputMeasure, MetricType from dbt_semantic_interfaces.protocols.semantic_manifest import SemanticManifest from dbt_semantic_interfaces.references import MeasureReference, MetricReference +from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity from metricflow_semantics.errors.error_classes import DuplicateMetricError, MetricNotFoundError, NonExistentMeasureError from metricflow_semantics.model.linkable_element_property import LinkableElementProperty @@ -186,3 +187,26 @@ def get_valid_agg_time_dimensions_for_metric( entity_links=agg_time_dimension_entity_links, ) return valid_agg_time_dimension_specs + + def get_min_queryable_time_granularity(self, metric_reference: MetricReference) -> TimeGranularity: + """The minimum grain that can be queried with this metric. + + Maps to the largest granularity defined for any of the metric's agg_time_dimensions. + """ + agg_time_dimension_specs = self._get_agg_time_dimension_specs_for_metric(metric_reference) + assert ( + agg_time_dimension_specs + ), f"No agg_time_dimension found for metric {metric_reference}. Something has been misconfigured." + + minimum_queryable_granularity = self._semantic_model_lookup.get_defined_time_granularity( + agg_time_dimension_specs[0].reference + ) + if len(agg_time_dimension_specs) > 1: + for agg_time_dimension_spec in agg_time_dimension_specs[1:]: + defined_time_granularity = self._semantic_model_lookup.get_defined_time_granularity( + agg_time_dimension_spec.reference + ) + if defined_time_granularity.to_int() > minimum_queryable_granularity.to_int(): + minimum_queryable_granularity = defined_time_granularity + + return minimum_queryable_granularity diff --git a/metricflow-semantics/metricflow_semantics/model/semantics/semantic_model_lookup.py b/metricflow-semantics/metricflow_semantics/model/semantics/semantic_model_lookup.py index a16783a55b..d820efb9a0 100644 --- a/metricflow-semantics/metricflow_semantics/model/semantics/semantic_model_lookup.py +++ b/metricflow-semantics/metricflow_semantics/model/semantics/semantic_model_lookup.py @@ -18,14 +18,14 @@ SemanticModelReference, TimeDimensionReference, ) -from dbt_semantic_interfaces.type_enums import DimensionType, EntityType -from dbt_semantic_interfaces.type_enums.aggregation_type import AggregationType +from dbt_semantic_interfaces.type_enums import AggregationType, DimensionType, EntityType, TimeGranularity from metricflow_semantics.errors.error_classes import InvalidSemanticModelError from metricflow_semantics.mf_logging.pretty_print import mf_pformat from metricflow_semantics.model.semantics.element_group import ElementGrouper from metricflow_semantics.model.spec_converters import MeasureConverter from metricflow_semantics.specs.spec_classes import ( + DEFAULT_TIME_GRANULARITY, DimensionSpec, EntitySpec, LinkableInstanceSpec, @@ -85,10 +85,13 @@ def get_dimension_from_semantic_model( def get_dimension(self, dimension_reference: DimensionReference) -> Dimension: """Retrieves a full dimension object by name.""" + # If the reference passed is a TimeDimensionReference, convert to DimensionReference. + dimension_reference = DimensionReference(dimension_reference.element_name) + semantic_models = self._dimension_index.get(dimension_reference) if not semantic_models: raise ValueError( - f"Could not find dimension with name ({dimension_reference.element_name}) in configured semantic models" + f"Could not find dimension with name '{dimension_reference.element_name}' in configured semantic models" ) dimension = SemanticModelLookup.get_dimension_from_semantic_model( @@ -366,3 +369,13 @@ def get_agg_time_dimension_specs_for_measure( time_dimension_reference=agg_time_dimension, entity_links=(entity_link,), ) + + def get_defined_time_granularity(self, time_dimension_reference: TimeDimensionReference) -> TimeGranularity: + """Time granularity from the time dimension's YAML definition. If not set, defaults to DAY.""" + time_dimension = self.get_dimension(time_dimension_reference) + + defined_time_granularity = DEFAULT_TIME_GRANULARITY + if time_dimension.type_params and time_dimension.type_params.time_granularity: + defined_time_granularity = time_dimension.type_params.time_granularity + + return defined_time_granularity From 09e5d8e035e1d51552ba1b856a10b6fdeb52463b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 17:22:11 -0700 Subject: [PATCH 17/26] Build DataflowPlan for cumulative metrics queried with non-default granularity --- .../dataflow/builder/dataflow_plan_builder.py | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/metricflow/dataflow/builder/dataflow_plan_builder.py b/metricflow/dataflow/builder/dataflow_plan_builder.py index 9298fd8478..ef1913c06f 100644 --- a/metricflow/dataflow/builder/dataflow_plan_builder.py +++ b/metricflow/dataflow/builder/dataflow_plan_builder.py @@ -79,6 +79,7 @@ from metricflow.dataflow.nodes.order_by_limit import OrderByLimitNode from metricflow.dataflow.nodes.semi_additive_join import SemiAdditiveJoinNode from metricflow.dataflow.nodes.where_filter import WhereConstraintNode +from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode from metricflow.dataflow.optimizer.dataflow_plan_optimizer import DataflowPlanOptimizer @@ -411,6 +412,57 @@ def _build_conversion_metric_output_node( aggregated_to_elements=set(queried_linkable_specs.as_tuple), ) + def _build_cumulative_metric_output_node( + self, + metric_spec: MetricSpec, + queried_linkable_specs: LinkableSpecSet, + filter_spec_factory: WhereSpecFactory, + predicate_pushdown_state: PredicatePushdownState, + for_group_by_source_node: bool = False, + ) -> DataflowPlanNode: + # TODO: replace with default_grain once added to YAML spec + default_granularity = self._metric_lookup.get_min_queryable_time_granularity(metric_spec.reference) + + queried_agg_time_dimensions = queried_linkable_specs.included_agg_time_dimension_specs_for_metric( + metric_reference=metric_spec.reference, metric_lookup=self._metric_lookup + ) + query_includes_agg_time_dimension_with_default_granularity = False + for time_dimension_spec in queried_agg_time_dimensions: + if time_dimension_spec.time_granularity == default_granularity: + query_includes_agg_time_dimension_with_default_granularity = True + break + + if query_includes_agg_time_dimension_with_default_granularity or not queried_agg_time_dimensions: + return self._build_base_metric_output_node( + metric_spec=metric_spec, + queried_linkable_specs=queried_linkable_specs, + filter_spec_factory=filter_spec_factory, + predicate_pushdown_state=predicate_pushdown_state, + for_group_by_source_node=for_group_by_source_node, + ) + + # If a cumulative metric is queried without default granularity, it will need to be aggregated twice - + # once as a normal metric, and again using a window function to narrow down to one row per granularity period. + # In this case, add metric time at the default granularity to the linkable specs. It will be used in the order by + # clause of the window function and later excluded from the output selections. + default_metric_time = DataSet.metric_time_dimension_spec(default_granularity) + include_linkable_specs = queried_linkable_specs.merge( + LinkableSpecSet(time_dimension_specs=(default_metric_time,)) + ) + compute_metrics_node = self._build_base_metric_output_node( + metric_spec=metric_spec, + queried_linkable_specs=include_linkable_specs, + filter_spec_factory=filter_spec_factory, + predicate_pushdown_state=predicate_pushdown_state, + for_group_by_source_node=for_group_by_source_node, + ) + return WindowReaggregationNode( + parent_node=compute_metrics_node, + metric_spec=metric_spec, + order_by_spec=default_metric_time, + partition_by_specs=queried_linkable_specs.as_tuple, + ) + def _build_base_metric_output_node( self, metric_spec: MetricSpec, @@ -585,7 +637,7 @@ def _build_any_metric_output_node( """Builds a node to compute a metric of any type.""" metric = self._metric_lookup.get_metric(metric_spec.reference) - if metric.type is MetricType.SIMPLE or metric.type is MetricType.CUMULATIVE: + if metric.type is MetricType.SIMPLE: return self._build_base_metric_output_node( metric_spec=metric_spec, queried_linkable_specs=queried_linkable_specs, @@ -594,6 +646,15 @@ def _build_any_metric_output_node( for_group_by_source_node=for_group_by_source_node, ) + elif metric.type is MetricType.CUMULATIVE: + return self._build_cumulative_metric_output_node( + metric_spec=metric_spec, + queried_linkable_specs=queried_linkable_specs, + filter_spec_factory=filter_spec_factory, + predicate_pushdown_state=predicate_pushdown_state, + for_group_by_source_node=for_group_by_source_node, + ) + elif metric.type is MetricType.RATIO or metric.type is MetricType.DERIVED: return self._build_derived_metric_output_node( metric_spec=metric_spec, @@ -1351,7 +1412,7 @@ def _build_aggregated_measure_from_measure_source_node( measure_reference=measure_spec.reference, semantic_model_lookup=self._semantic_model_lookup ) - # If a cumulative metric is queried with metric_time, join over time range. + # If a cumulative metric is queried with metric_time / agg_time_dimension, join over time range. # Otherwise, the measure will be aggregated over all time. time_range_node: Optional[JoinOverTimeRangeNode] = None if cumulative and queried_agg_time_dimension_specs: From ce72cf149d95a6f7460d2752f0ad0f5a2c2a42db Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 13 Jun 2024 17:23:21 -0700 Subject: [PATCH 18/26] Changelog --- .changes/unreleased/Features-20240613-172315.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Features-20240613-172315.yaml diff --git a/.changes/unreleased/Features-20240613-172315.yaml b/.changes/unreleased/Features-20240613-172315.yaml new file mode 100644 index 0000000000..401eb1359a --- /dev/null +++ b/.changes/unreleased/Features-20240613-172315.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Build dataflow plan for cumulative metrics queried with non-default granularity. +time: 2024-06-13T17:23:15.095339-07:00 +custom: + Author: courtneyholcomb + Issue: "1281" From 644bb5d5f2513ed5b555ce26733f0d8287c19575 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 07:02:28 -0700 Subject: [PATCH 19/26] Remove base time grain restriction for cumulative metrics --- .../candidate_push_down/push_down_visitor.py | 14 +------------- ...tems__accumulate_last_2_months_metric__set0.txt | 2 ++ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py b/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py index 2256db8a60..de488ad68b 100644 --- a/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py +++ b/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py @@ -46,7 +46,6 @@ MetricFlowQueryResolutionIssueSet, ) from metricflow_semantics.query.suggestion_generator import QueryItemSuggestionGenerator -from metricflow_semantics.specs.patterns.base_time_grain import BaseTimeGrainPattern from metricflow_semantics.specs.patterns.none_date_part import NoneDatePartPattern from metricflow_semantics.specs.patterns.spec_pattern import SpecPattern @@ -171,19 +170,8 @@ def visit_measure_node(self, node: MeasureGroupByItemSourceNode) -> PushDownResu elif metric.type is MetricType.RATIO or metric.type is MetricType.DERIVED: assert False, f"A measure should have a simple or cumulative metric as a child, but got {metric.type}" elif metric.type is MetricType.CUMULATIVE: - # To handle the restriction that cumulative metrics can only be queried at the base grain, it's - # easiest to handle that by applying the pattern to remove non-base grain time dimension specs at the - # measure node and generate the issue here if there's nothing that matches. Generating the issue here - # allows for creation of a more specific issue (i.e. include the measure) vs. generating the issue - # at a higher level. This can be more cleanly handled once we add additional context to the - # LinkableInstanceSpec. patterns_to_apply = ( - # From comment in ValidLinkableSpecResolver: - # It's possible to aggregate measures to coarser time granularities - # (except with cumulative metrics). - BaseTimeGrainPattern(only_apply_for_metric_time=True), - # From comment in previous query parser: - # Cannot extract date part for cumulative metrics. + # Date part doesn't make clear sense with cumulative metrics, so we don't allow it. NoneDatePartPattern(), ) else: diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_available_group_by_items.py/LinkableSpecSet/test_available_group_by_items__accumulate_last_2_months_metric__set0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_available_group_by_items.py/LinkableSpecSet/test_available_group_by_items__accumulate_last_2_months_metric__set0.txt index 5471827922..6d8275d0c1 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_available_group_by_items.py/LinkableSpecSet/test_available_group_by_items__accumulate_last_2_months_metric__set0.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_available_group_by_items.py/LinkableSpecSet/test_available_group_by_items__accumulate_last_2_months_metric__set0.txt @@ -1,5 +1,7 @@ [ "TimeDimension('metric_time', 'month')", + "TimeDimension('metric_time', 'quarter')", + "TimeDimension('metric_time', 'year')", "TimeDimension('monthly_measure_entity__creation_time', 'month')", "TimeDimension('monthly_measure_entity__creation_time', 'quarter')", "TimeDimension('monthly_measure_entity__creation_time', 'year')", From 9fe0996a2aa68d6593267e9151792567ce191aaa Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 07:11:18 -0700 Subject: [PATCH 20/26] Changelog --- .changes/unreleased/Features-20240614-071108.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Features-20240614-071108.yaml diff --git a/.changes/unreleased/Features-20240614-071108.yaml b/.changes/unreleased/Features-20240614-071108.yaml new file mode 100644 index 0000000000..7b6e1a8eac --- /dev/null +++ b/.changes/unreleased/Features-20240614-071108.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Remove restriction on querying non-default granularities with cumulative metrics. +time: 2024-06-14T07:11:08.765605-07:00 +custom: + Author: courtneyholcomb + Issue: "1282" From ae72a156ad9932b551857bf1b1bd8933e65ef2b7 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 08:10:04 -0700 Subject: [PATCH 21/26] Include source_spec_patterns in log --- .../group_by_item/candidate_push_down/push_down_visitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py b/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py index de488ad68b..4330579e26 100644 --- a/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py +++ b/metricflow-semantics/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py @@ -186,7 +186,7 @@ def visit_measure_node(self, node: MeasureGroupByItemSourceNode) -> PushDownResu f"For {node.ui_description}:\n" + indent( "After applying patterns:\n" - + indent(mf_pformat(patterns_to_apply)) + + indent(mf_pformat(patterns_to_apply + self._source_spec_patterns)) + "\n" + "to inputs, matches are:\n" + indent(mf_pformat(matching_items.specs)) From 9891bbf3022a464842622d4443d9b5f8cd909417 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 07:45:24 -0700 Subject: [PATCH 22/26] Dataflow plan tests --- .../builder/test_dataflow_plan_builder.py | 54 ++++++++++++++++++ ...e_metric_with_non_default_grain__dfp_0.xml | 51 +++++++++++++++++ ...e_metric_with_non_default_grain__dfp_0.xml | 56 +++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_non_default_grain__dfp_0.xml create mode 100644 tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_cumulative_metric_with_non_default_grain__dfp_0.xml diff --git a/tests_metricflow/dataflow/builder/test_dataflow_plan_builder.py b/tests_metricflow/dataflow/builder/test_dataflow_plan_builder.py index bd4b39f432..3dfed14897 100644 --- a/tests_metricflow/dataflow/builder/test_dataflow_plan_builder.py +++ b/tests_metricflow/dataflow/builder/test_dataflow_plan_builder.py @@ -1351,3 +1351,57 @@ def test_all_available_metric_filters( ), ).query_spec dataflow_plan_builder.build_plan(query_spec) + + +def test_cumulative_metric_with_non_default_grain( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test querying a cumulative metric using a granularity that is not the metric's default.""" + query_spec = query_parser.parse_and_validate_query( + metric_names=("trailing_2_months_revenue",), group_by_names=("metric_time__year",) + ).query_spec + dataflow_plan = dataflow_plan_builder.build_plan(query_spec) + + assert_plan_snapshot_text_equal( + request=request, + mf_test_configuration=mf_test_configuration, + plan=dataflow_plan, + plan_snapshot_text=dataflow_plan.structure_text(), + ) + + display_graph_if_requested( + request=request, + mf_test_configuration=mf_test_configuration, + dag_graph=dataflow_plan, + ) + + +def test_derived_cumulative_metric_with_non_default_grain( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + query_parser: MetricFlowQueryParser, + create_source_tables: bool, +) -> None: + """Test querying a derived metric with a cumulative input metric using non-default granularity.""" + query_spec = query_parser.parse_and_validate_query( + metric_names=("trailing_2_months_revenue_sub_10",), group_by_names=("metric_time__month",) + ).query_spec + dataflow_plan = dataflow_plan_builder.build_plan(query_spec) + + assert_plan_snapshot_text_equal( + request=request, + mf_test_configuration=mf_test_configuration, + plan=dataflow_plan, + plan_snapshot_text=dataflow_plan.structure_text(), + ) + + display_graph_if_requested( + request=request, + mf_test_configuration=mf_test_configuration, + dag_graph=dataflow_plan, + ) diff --git a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_non_default_grain__dfp_0.xml b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_non_default_grain__dfp_0.xml new file mode 100644 index 0000000000..4352536fd0 --- /dev/null +++ b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_cumulative_metric_with_non_default_grain__dfp_0.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_cumulative_metric_with_non_default_grain__dfp_0.xml b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_cumulative_metric_with_non_default_grain__dfp_0.xml new file mode 100644 index 0000000000..e7e2471f97 --- /dev/null +++ b/tests_metricflow/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_derived_cumulative_metric_with_non_default_grain__dfp_0.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 21777137ea9a97d6502c219c56c5be451671dc9b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 13:35:16 -0700 Subject: [PATCH 23/26] Check query tests --- .../test_cases/itest_cumulative_metric.yaml | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/tests_metricflow/integration/test_cases/itest_cumulative_metric.yaml b/tests_metricflow/integration/test_cases/itest_cumulative_metric.yaml index a854eb2846..1e8951f331 100644 --- a/tests_metricflow/integration/test_cases/itest_cumulative_metric.yaml +++ b/tests_metricflow/integration/test_cases/itest_cumulative_metric.yaml @@ -412,3 +412,183 @@ integration_test: WHERE {{ render_time_constraint("a.ds", "2020-03-05", "2021-01-04") }} GROUP BY a.ds ORDER BY a.ds +--- +integration_test: + name: all_time_metric_with_non_default_grains + description: Query a cumulative all-time metric with non-default grains + model: SIMPLE_MODEL + metrics: ["revenue_all_time"] + group_bys: ["metric_time__week", "metric_time__quarter"] + check_query: | + SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time + FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week, metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + SELECT + t.ds AS metric_time__day + , {{ render_date_trunc("T.ds", TimeGranularity.WEEK) }} AS metric_time__week + , {{ render_date_trunc("t.ds", TimeGranularity.QUARTER) }} AS metric_time__quarter + , SUM(r.revenue) AS revenue_all_time + FROM {{ source_schema }}.mf_time_spine t + INNER JOIN {{ source_schema }}.fct_revenue r ON {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} <= t.ds + GROUP BY + t.ds + , {{ render_date_trunc("t.ds", TimeGranularity.WEEK) }} + , {{ render_date_trunc("t.ds", TimeGranularity.QUARTER) }} + ) subq_7 + ) subq_8 + GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time +--- +integration_test: + name: window_metric_with_non_default_grains + description: Query a cumulative window metric with non-default grains + model: SIMPLE_MODEL + metrics: ["trailing_2_months_revenue"] + group_bys: ["metric_time__week", "revenue_instance__ds__month"] + check_query: | + SELECT + revenue_instance__ds__month + , metric_time__week + , trailing_2_months_revenue + FROM ( + SELECT + revenue_instance__ds__month + , metric_time__week + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY revenue_instance__ds__month, metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + SELECT + {{ render_date_trunc("t.ds", TimeGranularity.MONTH) }} AS revenue_instance__ds__month + , t.ds AS metric_time__day + , {{ render_date_trunc("t.ds", TimeGranularity.WEEK) }} AS metric_time__week + , SUM(r.revenue) AS trailing_2_months_revenue + FROM {{ source_schema }}.mf_time_spine t + INNER JOIN {{ source_schema }}.fct_revenue r + ON + ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} <= t.ds + ) AND ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} > {{ render_date_sub("t", "ds", 2, TimeGranularity.MONTH) }} + ) + GROUP BY + {{ render_date_trunc("t.ds", TimeGranularity.MONTH) }} + , t.ds + , {{ render_date_trunc("t.ds", TimeGranularity.WEEK) }} + ) subq_7 + ) subq_8 + GROUP BY + revenue_instance__ds__month + , metric_time__week + , trailing_2_months_revenue +--- +integration_test: + name: grain_to_date_metric_with_non_default_grains + description: Query a cumulative grain to date metric with non-default grains + model: SIMPLE_MODEL + metrics: ["revenue_mtd"] + group_bys: ["revenue_instance__ds__quarter", "revenue_instance__ds__year"] + check_query: | + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd + FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY revenue_instance__ds__quarter, revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + SELECT + {{ render_date_trunc("t.ds", TimeGranularity.QUARTER) }} AS revenue_instance__ds__quarter + , {{ render_date_trunc("t.ds", TimeGranularity.YEAR) }} AS revenue_instance__ds__year + , t.ds AS metric_time__day + , SUM(r.revenue) AS revenue_mtd + FROM {{ source_schema }}.mf_time_spine t + INNER JOIN {{ source_schema }}.fct_revenue r + ON + ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} <= t.ds + ) AND ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} >= {{ render_date_trunc("t.ds", TimeGranularity.MONTH) }} + ) + GROUP BY + {{ render_date_trunc("t.ds", TimeGranularity.QUARTER) }} + , {{ render_date_trunc("t.ds", TimeGranularity.YEAR) }} + , t.ds + ) subq_7 + ) subq_8 + GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +--- +integration_test: + name: derived_cumulative_metric_with_non_default_grains + description: Query a derived cumulative metric with non-default grains + model: SIMPLE_MODEL + metrics: ["trailing_2_months_revenue_sub_10"] + group_bys: ["metric_time__month", "metric_time__year"] + check_query: | + SELECT + metric_time__month + , metric_time__year + , t2mr - 10 AS trailing_2_months_revenue_sub_10 + FROM ( + SELECT + metric_time__month + , metric_time__year + , t2mr + FROM ( + SELECT + metric_time__month + , metric_time__year + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__month, metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + SELECT + t.ds AS metric_time__day + , {{ render_date_trunc("t.ds", TimeGranularity.MONTH) }} AS metric_time__month + , {{ render_date_trunc("t.ds", TimeGranularity.YEAR) }} AS metric_time__year + , SUM(r.revenue) AS t2mr + FROM {{ source_schema }}.mf_time_spine t + INNER JOIN {{ source_schema }}.fct_revenue r + ON + ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} <= t.ds + ) AND ( + {{ render_date_trunc("r.created_at", TimeGranularity.DAY) }} > {{ render_date_sub("t", "ds", 2, TimeGranularity.MONTH) }} + ) + GROUP BY + t.ds + , {{ render_date_trunc("t.ds", TimeGranularity.MONTH) }} + , {{ render_date_trunc("t.ds", TimeGranularity.YEAR) }} + ) subq_7 + ) subq_8 + GROUP BY + metric_time__month + , metric_time__year + , t2mr + ) subq_9 From 571e03c82fb3e16a2b83e613a88fecd1a23893e9 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 13:36:25 -0700 Subject: [PATCH 24/26] SQL rendering tests --- .../test_cumulative_metric_rendering.py | 236 ++++++++++- ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ 15 files changed, 1989 insertions(+), 12 deletions(-) create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0_optimized.sql diff --git a/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py b/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py index 17c1fd6d7f..1724861a87 100644 --- a/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py +++ b/tests_metricflow/query_rendering/test_cumulative_metric_rendering.py @@ -16,7 +16,13 @@ from metricflow_semantics.specs.query_spec import MetricFlowQuerySpec from metricflow_semantics.specs.spec_classes import EntityReference, MetricSpec, TimeDimensionSpec from metricflow_semantics.test_helpers.config_helpers import MetricFlowTestConfiguration -from metricflow_semantics.test_helpers.metric_time_dimension import MTD_SPEC_DAY, MTD_SPEC_MONTH +from metricflow_semantics.test_helpers.metric_time_dimension import ( + MTD_SPEC_DAY, + MTD_SPEC_MONTH, + MTD_SPEC_QUARTER, + MTD_SPEC_WEEK, + MTD_SPEC_YEAR, +) from metricflow.dataflow.builder.dataflow_plan_builder import DataflowPlanBuilder from metricflow.plan_conversion.dataflow_to_sql import DataflowToSqlQueryPlanConverter @@ -38,7 +44,6 @@ def test_cumulative_metric( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec( element_name="ds", @@ -76,7 +81,6 @@ def test_cumulative_metric_with_time_constraint( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec( element_name="metric_time", @@ -150,7 +154,6 @@ def test_cumulative_metric_no_ds( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=(), ) ) @@ -177,7 +180,6 @@ def test_cumulative_metric_no_window( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="revenue_all_time"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec( element_name="ds", @@ -210,7 +212,6 @@ def test_cumulative_metric_no_window_with_time_constraint( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="revenue_all_time"),), - dimension_specs=(), time_dimension_specs=(MTD_SPEC_DAY,), time_range_constraint=TimeRangeConstraint( start_time=as_datetime("2020-01-01"), end_time=as_datetime("2020-01-01") @@ -240,7 +241,6 @@ def test_cumulative_metric_grain_to_date( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="revenue_mtd"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec( element_name="ds", @@ -273,7 +273,6 @@ def test_cumulative_metric_month( dataflow_plan = extended_date_dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_3_months_bookings"),), - dimension_specs=(), time_dimension_specs=(MTD_SPEC_MONTH,), time_range_constraint=TimeRangeConstraint( start_time=as_datetime("2020-03-05"), end_time=as_datetime("2021-01-04") @@ -303,7 +302,6 @@ def test_cumulative_metric_with_agg_time_dimension( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec(element_name="ds", entity_links=(EntityReference("revenue_instance"),)), ), @@ -332,7 +330,6 @@ def test_cumulative_metric_with_multiple_agg_time_dimensions( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=( TimeDimensionSpec( element_name="ds", @@ -370,7 +367,6 @@ def test_cumulative_metric_with_multiple_metric_time_dimensions( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=(MTD_SPEC_DAY, MTD_SPEC_MONTH), ) ) @@ -397,7 +393,6 @@ def test_cumulative_metric_with_agg_time_and_metric_time( dataflow_plan = dataflow_plan_builder.build_plan( MetricFlowQuerySpec( metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), - dimension_specs=(), time_dimension_specs=( MTD_SPEC_DAY, TimeDimensionSpec( @@ -416,3 +411,220 @@ def test_cumulative_metric_with_agg_time_and_metric_time( sql_client=sql_client, node=dataflow_plan.sink_node, ) + + +@pytest.mark.sql_engine_snapshot +def test_cumulative_metric_with_non_default_grain( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative all-time metric queried with non-default grain.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="revenue_all_time"),), + time_dimension_specs=(MTD_SPEC_WEEK,), + ) + ) + + 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_window_metric_with_non_default_grain( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative window metric queried with non-default grain.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="trailing_2_months_revenue"),), + time_dimension_specs=(MTD_SPEC_YEAR,), + ) + ) + + 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_grain_to_date_metric_with_non_default_grain( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative grain to date metric queried with non-default grain.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="revenue_mtd"),), + time_dimension_specs=(MTD_SPEC_MONTH,), + ) + ) + + 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_window_metric_with_non_default_grains( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative window metric queried with non-default grains. + + Uses both metric_time and agg_time_dimension. Excludes default grain. + """ + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="every_two_days_bookers_fill_nulls_with_0"),), + time_dimension_specs=( + MTD_SPEC_WEEK, + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("booking"),), + time_granularity=TimeGranularity.MONTH, + ), + ), + ) + ) + + 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_grain_to_date_metric_with_non_default_grains( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative grain to date metric queried with non-default grains. + + Uses agg time dimension instead of metric_time. Excludes default grain. + """ + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="revenue_mtd"),), + time_dimension_specs=( + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("revenue_instance"),), + time_granularity=TimeGranularity.QUARTER, + ), + TimeDimensionSpec( + element_name="ds", + entity_links=(EntityReference("revenue_instance"),), + time_granularity=TimeGranularity.YEAR, + ), + ), + ) + ) + + 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_all_time_metric_with_non_default_grains( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Tests rendering a query for a cumulative all-time metric queried with non-default grains. + + Uses only metric_time. Excludes default grain. + """ + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="revenue_all_time"),), + time_dimension_specs=(MTD_SPEC_WEEK, MTD_SPEC_QUARTER), + ) + ) + + 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_derived_cumulative_metric_with_non_default_grains( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture], + sql_client: SqlClient, +) -> None: + """Test querying a derived metric with a cumulative input metric using non-default grains.""" + dataflow_plan = dataflow_plan_builder.build_plan( + MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name="trailing_2_months_revenue_sub_10"),), + time_dimension_specs=(MTD_SPEC_WEEK,), + ) + ) + + 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, + ) + + +# TODO: write the following tests when unblocked +# - Render each of the allowed period_aggs (both set in YAML & default) +# - Query cumulative metric with non-day default_grain (using default grain and non-default grain) +# - Query 2 metrics with different default_grains using metric_time (no grain specified) +# - If default grain is WEEK, query with a higher grain (check that we still get correct values) +# - Query cumulative metric with sub-daily grain diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..76db060e40 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..adee85c66f --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..a6005ff109 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - INTERVAL 2 month + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..f8eb61fe20 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_12.metric_time__day - INTERVAL 2 month + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..1f970f5692 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..824539bb13 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..5b9bc20a85 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - INTERVAL 2 month + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..8e1ddcdede --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_11.metric_time__day - INTERVAL 2 month + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..c2a9e67489 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - INTERVAL 2 day + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..c90b3dac02 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/DuckDB/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > subq_14.metric_time__day - INTERVAL 2 day + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 From 72912f4144cbd16375eb859bafc2614ff0ce49eb Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 14 Jun 2024 13:44:44 -0700 Subject: [PATCH 25/26] SQL engine snapshots --- ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ ..._metric_with_non_default_grains__plan0.sql | 173 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 54 +++ ...e_metric_with_non_default_grain__plan0.sql | 162 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 45 +++ ..._metric_with_non_default_grains__plan0.sql | 172 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 53 +++ ...e_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 177 ++++++++ ...th_non_default_grains__plan0_optimized.sql | 56 +++ ...w_metric_with_non_default_grain__plan0.sql | 166 ++++++++ ...ith_non_default_grain__plan0_optimized.sql | 47 +++ ..._metric_with_non_default_grains__plan0.sql | 380 ++++++++++++++++++ ...th_non_default_grains__plan0_optimized.sql | 67 +++ 84 files changed, 10590 insertions(+) create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0.sql create mode 100644 tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0_optimized.sql diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..ac132ac3be --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, isoweek) AS metric_time__week + , DATETIME_TRUNC(subq_3.ds, quarter) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__week + , metric_time__quarter + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__week + , metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..9a07426358 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, isoweek) AS metric_time__week + , DATETIME_TRUNC(ds, quarter) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + metric_time__day + , metric_time__week + , metric_time__quarter + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_11.metric_time__day + ) + GROUP BY + metric_time__day + , metric_time__week + , metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..935bd3b774 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__week + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..679138e76b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + metric_time__day + , metric_time__week + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_11.metric_time__day + ) + GROUP BY + metric_time__day + , metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..71bf0ab1e9 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__week + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_SUB(CAST(subq_2.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + metric_time__week + , t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..2d34b10b05 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + metric_time__day + , metric_time__week + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_12.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) > DATE_SUB(CAST(subq_12.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + GROUP BY + metric_time__day + , metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..eb7781ad5e --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, month) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__month + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATETIME_TRUNC(subq_2.metric_time__day, month) + ) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..d4f60f72ba --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, month) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + metric_time__day + , metric_time__month + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_11.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) >= DATETIME_TRUNC(subq_11.metric_time__day, month) + ) + GROUP BY + metric_time__day + , metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..c3dacc4b79 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(subq_3.ds, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(subq_3.ds, year) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , metric_time__day + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATETIME_TRUNC(subq_2.metric_time__day, month) + ) + ) subq_4 + ) subq_5 + GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..ac4b955522 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(ds, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(ds, year) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , metric_time__day + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_11.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) >= DATETIME_TRUNC(subq_11.metric_time__day, month) + ) + GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..241bee8b7e --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, year) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + metric_time__day + , metric_time__year + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATETIME_TRUNC(revenue_src_28000.created_at, day) AS revenue_instance__ds__day + , DATETIME_TRUNC(revenue_src_28000.created_at, isoweek) AS revenue_instance__ds__week + , DATETIME_TRUNC(revenue_src_28000.created_at, month) AS revenue_instance__ds__month + , DATETIME_TRUNC(revenue_src_28000.created_at, quarter) AS revenue_instance__ds__quarter + , DATETIME_TRUNC(revenue_src_28000.created_at, year) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , IF(EXTRACT(dayofweek FROM revenue_src_28000.created_at) = 1, 7, EXTRACT(dayofweek FROM revenue_src_28000.created_at) - 1) AS revenue_instance__ds__extract_dow + , EXTRACT(dayofyear FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_SUB(CAST(subq_2.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + ) subq_4 + ) subq_5 + GROUP BY + metric_time__day + , metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..4172ca73b4 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATETIME_TRUNC(ds, year) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + metric_time__day + , metric_time__year + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) <= subq_11.metric_time__day + ) AND ( + DATETIME_TRUNC(revenue_src_28000.created_at, day) > DATE_SUB(CAST(subq_11.metric_time__day AS DATETIME), INTERVAL 2 month) + ) + GROUP BY + metric_time__day + , metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..3d2ef9d231 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATETIME_TRUNC(subq_7.metric_time__day, isoweek) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(subq_3.ds, month) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATETIME_TRUNC(subq_3.ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + booking__ds__month + , metric_time__day + , metric_time__week + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATETIME_TRUNC(bookings_source_src_28000.ds, day) AS ds__day + , DATETIME_TRUNC(bookings_source_src_28000.ds, isoweek) AS ds__week + , DATETIME_TRUNC(bookings_source_src_28000.ds, month) AS ds__month + , DATETIME_TRUNC(bookings_source_src_28000.ds, quarter) AS ds__quarter + , DATETIME_TRUNC(bookings_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS ds_partitioned__day + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS ds_partitioned__week + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS ds_partitioned__month + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS ds_partitioned__quarter + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, day) AS paid_at__day + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS paid_at__week + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, month) AS paid_at__month + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, quarter) AS paid_at__quarter + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, year) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATETIME_TRUNC(bookings_source_src_28000.ds, day) AS booking__ds__day + , DATETIME_TRUNC(bookings_source_src_28000.ds, isoweek) AS booking__ds__week + , DATETIME_TRUNC(bookings_source_src_28000.ds, month) AS booking__ds__month + , DATETIME_TRUNC(bookings_source_src_28000.ds, quarter) AS booking__ds__quarter + , DATETIME_TRUNC(bookings_source_src_28000.ds, year) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS booking__ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS booking__ds_partitioned__day + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS booking__ds_partitioned__week + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS booking__ds_partitioned__month + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS booking__ds_partitioned__quarter + , DATETIME_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS booking__ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, day) AS booking__paid_at__day + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS booking__paid_at__week + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, month) AS booking__paid_at__month + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, quarter) AS booking__paid_at__quarter + , DATETIME_TRUNC(bookings_source_src_28000.paid_at, year) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS booking__paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_SUB(CAST(subq_2.metric_time__day AS DATETIME), INTERVAL 2 day) + ) + ) subq_4 + ) subq_5 + GROUP BY + booking__ds__month + , metric_time__day + , metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..90bc403ad4 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/BigQuery/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATETIME_TRUNC(subq_20.ds, isoweek) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATETIME_TRUNC(ds, month) AS booking__ds__month + , ds AS metric_time__day + , DATETIME_TRUNC(ds, isoweek) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + booking__ds__month + , metric_time__day + , metric_time__week + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATETIME_TRUNC(bookings_source_src_28000.ds, day) <= subq_14.metric_time__day + ) AND ( + DATETIME_TRUNC(bookings_source_src_28000.ds, day) > DATE_SUB(CAST(subq_14.metric_time__day AS DATETIME), INTERVAL 2 day) + ) + GROUP BY + booking__ds__month + , metric_time__day + , metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..68b9e2e19b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..5c95a99d0a --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..5f61ed6669 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..4fdfdfb1ea --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_12.metric_time__day) + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..e08fcb6000 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..e8f84887db --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..08b4f6eb3a --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..6ba57d18bf --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..e2ebdfa01b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(day, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..cfe2fe5a31 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Databricks/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > DATEADD(day, -2, subq_14.metric_time__day) + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..76db060e40 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..adee85c66f --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..af3b184069 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - MAKE_INTERVAL(months => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..1a3212375a --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_12.metric_time__day - MAKE_INTERVAL(months => 2) + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..1f970f5692 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..824539bb13 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..87206b51c0 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(isodow FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - MAKE_INTERVAL(months => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..a36b931172 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > subq_11.metric_time__day - MAKE_INTERVAL(months => 2) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..9932a10f54 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > subq_2.metric_time__day - MAKE_INTERVAL(days => 2) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..15ba379cc7 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Postgres/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > subq_14.metric_time__day - MAKE_INTERVAL(days => 2) + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..b1e81fd313 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..8dca333b86 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..779b78ce33 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..4fdfdfb1ea --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_12.metric_time__day) + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..3b29b96b31 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..9482f94e18 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..ce0c265f3c --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , CASE WHEN EXTRACT(dow FROM revenue_src_28000.created_at) = 0 THEN EXTRACT(dow FROM revenue_src_28000.created_at) + 7 ELSE EXTRACT(dow FROM revenue_src_28000.created_at) END AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..6ba57d18bf --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..9bb7d74ede --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(day, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..cfe2fe5a31 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Redshift/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > DATEADD(day, -2, subq_14.metric_time__day) + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..5844b512e0 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..f21ddefd0c --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..f0d13e89f0 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..4fdfdfb1ea --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_12.metric_time__day) + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..74ce81f024 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..2723a3aa72 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..5124533e5d --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(dayofweekiso FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(month, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..6ba57d18bf --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATEADD(month, -2, subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..accc35438c --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATEADD(day, -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..cfe2fe5a31 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Snowflake/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > DATEADD(day, -2, subq_14.metric_time__day) + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..c28f38fc18 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,173 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , subq_7.metric_time__quarter + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY + subq_7.metric_time__week + , subq_7.metric_time__quarter + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__quarter + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.metric_time__quarter + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + , DATE_TRUNC('quarter', subq_3.ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + , DATE_TRUNC('quarter', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + , subq_5.metric_time__quarter + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.metric_time__quarter + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..47f50d7e6b --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_all_time_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,54 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , metric_time__quarter + , revenue_all_time +FROM ( + SELECT + metric_time__week + , metric_time__quarter + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY + metric_time__week + , metric_time__quarter + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__quarter', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_11.metric_time__quarter AS metric_time__quarter + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , DATE_TRUNC('quarter', ds) AS metric_time__quarter + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + , DATE_TRUNC('quarter', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + , subq_11.metric_time__quarter + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , metric_time__quarter + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..cdbcddfe68 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,162 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__week + , subq_8.revenue_all_time +FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.revenue_all_time) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS revenue_all_time + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + (subq_1.metric_time__day <= subq_2.metric_time__day) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__week + , subq_8.revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..0f138fc252 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_cumulative_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,45 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , revenue_all_time +FROM ( + SELECT + metric_time__week + , FIRST_VALUE(revenue_all_time) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_all_time + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS revenue_all_time + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__week + ) subq_16 +) subq_17 +GROUP BY + metric_time__week + , revenue_all_time diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..3f448bf324 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,172 @@ +-- Compute Metrics via Expressions +SELECT + subq_9.metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + subq_8.metric_time__week + , subq_8.t2mr + FROM ( + SELECT + subq_7.metric_time__week + , FIRST_VALUE(subq_7.t2mr) OVER ( + PARTITION BY subq_7.metric_time__week + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.txn_revenue AS t2mr + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__week + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_ADD('month', -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ) subq_7 + ) subq_8 + GROUP BY + subq_8.metric_time__week + , subq_8.t2mr +) subq_9 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..fc095c62df --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_derived_cumulative_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,53 @@ +-- Compute Metrics via Expressions +SELECT + metric_time__week + , t2mr - 10 AS trailing_2_months_revenue_sub_10 +FROM ( + -- Re-aggregate Metrics via Window Functions + SELECT + metric_time__week + , t2mr + FROM ( + SELECT + metric_time__week + , FIRST_VALUE(t2mr) OVER ( + PARTITION BY metric_time__week + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS t2mr + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__week', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_12.metric_time__day AS metric_time__day + , subq_12.metric_time__week AS metric_time__week + , SUM(revenue_src_28000.revenue) AS t2mr + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_13 + GROUP BY + ds + , DATE_TRUNC('week', ds) + ) subq_12 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_12.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATE_ADD('month', -2, subq_12.metric_time__day) + ) + GROUP BY + subq_12.metric_time__day + , subq_12.metric_time__week + ) subq_17 + ) subq_18 + GROUP BY + metric_time__week + , t2mr +) subq_19 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..086aee871a --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__month + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.metric_time__month + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY subq_7.metric_time__month + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__month + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__month + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__month + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__month AS metric_time__month + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('month', subq_3.ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('month', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__month + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__month + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..e99370b8b2 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__month + , revenue_mtd +FROM ( + SELECT + metric_time__month + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY metric_time__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__month', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__month AS metric_time__month + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('month', ds) AS metric_time__month + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('month', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__month + ) subq_16 +) subq_17 +GROUP BY + metric_time__month + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..d428072f3d --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,177 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd +FROM ( + SELECT + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + , FIRST_VALUE(subq_7.revenue_mtd) OVER ( + PARTITION BY + subq_7.revenue_instance__ds__quarter + , subq_7.revenue_instance__ds__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.revenue_instance__ds__quarter + , subq_6.revenue_instance__ds__year + , subq_6.metric_time__day + , subq_6.txn_revenue AS revenue_mtd + FROM ( + -- Aggregate Measures + SELECT + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + SELECT + subq_4.revenue_instance__ds__quarter + , subq_4.revenue_instance__ds__year + , subq_4.metric_time__day + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_2.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_2.metric_time__day AS metric_time__day + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', subq_3.ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', subq_3.ds) AS revenue_instance__ds__year + , subq_3.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('quarter', subq_3.ds) + , DATE_TRUNC('year', subq_3.ds) + , subq_3.ds + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day >= DATE_TRUNC('month', subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.revenue_instance__ds__quarter + , subq_5.revenue_instance__ds__year + , subq_5.metric_time__day + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.revenue_instance__ds__quarter + , subq_8.revenue_instance__ds__year + , subq_8.revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..a86c1c9576 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_grain_to_date_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,56 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd +FROM ( + SELECT + revenue_instance__ds__quarter + , revenue_instance__ds__year + , FIRST_VALUE(revenue_mtd) OVER ( + PARTITION BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS revenue_mtd + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'revenue_instance__ds__quarter', 'revenue_instance__ds__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_11.metric_time__day AS metric_time__day + , SUM(revenue_src_28000.revenue) AS revenue_mtd + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('quarter', ds) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', ds) AS revenue_instance__ds__year + , ds AS metric_time__day + FROM ***************************.mf_time_spine subq_12 + GROUP BY + DATE_TRUNC('quarter', ds) + , DATE_TRUNC('year', ds) + , ds + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) >= DATE_TRUNC('month', subq_11.metric_time__day) + ) + GROUP BY + subq_11.revenue_instance__ds__quarter + , subq_11.revenue_instance__ds__year + , subq_11.metric_time__day + ) subq_16 +) subq_17 +GROUP BY + revenue_instance__ds__quarter + , revenue_instance__ds__year + , revenue_mtd diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0.sql new file mode 100644 index 0000000000..6ade36d3a9 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0.sql @@ -0,0 +1,166 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue +FROM ( + SELECT + subq_7.metric_time__year + , FIRST_VALUE(subq_7.trailing_2_months_revenue) OVER ( + PARTITION BY subq_7.metric_time__year + ORDER BY subq_7.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_6.metric_time__day + , subq_6.metric_time__year + , subq_6.txn_revenue AS trailing_2_months_revenue + FROM ( + -- Aggregate Measures + SELECT + subq_5.metric_time__day + , subq_5.metric_time__year + , SUM(subq_5.txn_revenue) AS txn_revenue + FROM ( + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + SELECT + subq_4.metric_time__day + , subq_4.metric_time__year + , subq_4.txn_revenue + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__year AS metric_time__year + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.revenue_instance__ds__day AS revenue_instance__ds__day + , subq_1.revenue_instance__ds__week AS revenue_instance__ds__week + , subq_1.revenue_instance__ds__month AS revenue_instance__ds__month + , subq_1.revenue_instance__ds__quarter AS revenue_instance__ds__quarter + , subq_1.revenue_instance__ds__year AS revenue_instance__ds__year + , subq_1.revenue_instance__ds__extract_year AS revenue_instance__ds__extract_year + , subq_1.revenue_instance__ds__extract_quarter AS revenue_instance__ds__extract_quarter + , subq_1.revenue_instance__ds__extract_month AS revenue_instance__ds__extract_month + , subq_1.revenue_instance__ds__extract_day AS revenue_instance__ds__extract_day + , subq_1.revenue_instance__ds__extract_dow AS revenue_instance__ds__extract_dow + , subq_1.revenue_instance__ds__extract_doy AS revenue_instance__ds__extract_doy + , subq_1.metric_time__week AS metric_time__week + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.user AS user + , subq_1.revenue_instance__user AS revenue_instance__user + , subq_1.txn_revenue AS txn_revenue + FROM ( + -- Time Spine + SELECT + subq_3.ds AS metric_time__day + , DATE_TRUNC('year', subq_3.ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_3 + GROUP BY + subq_3.ds + , DATE_TRUNC('year', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.revenue_instance__ds__day + , subq_0.revenue_instance__ds__week + , subq_0.revenue_instance__ds__month + , subq_0.revenue_instance__ds__quarter + , subq_0.revenue_instance__ds__year + , subq_0.revenue_instance__ds__extract_year + , subq_0.revenue_instance__ds__extract_quarter + , subq_0.revenue_instance__ds__extract_month + , subq_0.revenue_instance__ds__extract_day + , subq_0.revenue_instance__ds__extract_dow + , subq_0.revenue_instance__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.revenue_instance__user + , subq_0.txn_revenue + FROM ( + -- Read Elements From Semantic Model 'revenue' + SELECT + revenue_src_28000.revenue AS txn_revenue + , DATE_TRUNC('day', revenue_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', revenue_src_28000.created_at) AS revenue_instance__ds__day + , DATE_TRUNC('week', revenue_src_28000.created_at) AS revenue_instance__ds__week + , DATE_TRUNC('month', revenue_src_28000.created_at) AS revenue_instance__ds__month + , DATE_TRUNC('quarter', revenue_src_28000.created_at) AS revenue_instance__ds__quarter + , DATE_TRUNC('year', revenue_src_28000.created_at) AS revenue_instance__ds__year + , EXTRACT(year FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_year + , EXTRACT(quarter FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_quarter + , EXTRACT(month FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_month + , EXTRACT(day FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_dow + , EXTRACT(doy FROM revenue_src_28000.created_at) AS revenue_instance__ds__extract_doy + , revenue_src_28000.user_id AS user + , revenue_src_28000.user_id AS revenue_instance__user + FROM ***************************.fct_revenue revenue_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_ADD('month', -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.metric_time__day + , subq_5.metric_time__year + ) subq_6 + ) subq_7 +) subq_8 +GROUP BY + subq_8.metric_time__year + , subq_8.trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0_optimized.sql new file mode 100644 index 0000000000..bd4b1c264e --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grain__plan0_optimized.sql @@ -0,0 +1,47 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__year + , trailing_2_months_revenue +FROM ( + SELECT + metric_time__year + , FIRST_VALUE(trailing_2_months_revenue) OVER ( + PARTITION BY metric_time__year + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS trailing_2_months_revenue + FROM ( + -- Join Self Over Time Range + -- Pass Only Elements: ['txn_revenue', 'metric_time__year', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__year AS metric_time__year + , SUM(revenue_src_28000.revenue) AS trailing_2_months_revenue + FROM ( + -- Time Spine + SELECT + ds AS metric_time__day + , DATE_TRUNC('year', ds) AS metric_time__year + FROM ***************************.mf_time_spine subq_12 + GROUP BY + ds + , DATE_TRUNC('year', ds) + ) subq_11 + INNER JOIN + ***************************.fct_revenue revenue_src_28000 + ON + ( + DATE_TRUNC('day', revenue_src_28000.created_at) <= subq_11.metric_time__day + ) AND ( + DATE_TRUNC('day', revenue_src_28000.created_at) > DATE_ADD('month', -2, subq_11.metric_time__day) + ) + GROUP BY + subq_11.metric_time__day + , subq_11.metric_time__year + ) subq_16 +) subq_17 +GROUP BY + metric_time__year + , trailing_2_months_revenue diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0.sql new file mode 100644 index 0000000000..844f6f0566 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0.sql @@ -0,0 +1,380 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 +FROM ( + SELECT + subq_10.metric_time__week + , subq_10.booking__ds__month + , FIRST_VALUE(subq_10.every_two_days_bookers_fill_nulls_with_0) OVER ( + PARTITION BY + subq_10.metric_time__week + , subq_10.booking__ds__month + ORDER BY subq_10.metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.metric_time__day + , subq_9.metric_time__week + , subq_9.booking__ds__month + , COALESCE(subq_9.bookers, 0) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_7.metric_time__day AS metric_time__day + , DATE_TRUNC('week', subq_7.metric_time__day) AS metric_time__week + , subq_6.booking__ds__month AS booking__ds__month + , subq_6.bookers AS bookers + FROM ( + -- Time Spine + SELECT + subq_8.ds AS metric_time__day + FROM ***************************.mf_time_spine subq_8 + ) subq_7 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + , COUNT(DISTINCT subq_5.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + SELECT + subq_4.booking__ds__month + , subq_4.metric_time__day + , subq_4.metric_time__week + , subq_4.bookers + FROM ( + -- Join Self Over Time Range + SELECT + subq_2.booking__ds__month AS booking__ds__month + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_1.ds__day AS ds__day + , subq_1.ds__week AS ds__week + , subq_1.ds__month AS ds__month + , subq_1.ds__quarter AS ds__quarter + , subq_1.ds__year AS ds__year + , subq_1.ds__extract_year AS ds__extract_year + , subq_1.ds__extract_quarter AS ds__extract_quarter + , subq_1.ds__extract_month AS ds__extract_month + , subq_1.ds__extract_day AS ds__extract_day + , subq_1.ds__extract_dow AS ds__extract_dow + , subq_1.ds__extract_doy AS ds__extract_doy + , subq_1.ds_partitioned__day AS ds_partitioned__day + , subq_1.ds_partitioned__week AS ds_partitioned__week + , subq_1.ds_partitioned__month AS ds_partitioned__month + , subq_1.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_1.ds_partitioned__year AS ds_partitioned__year + , subq_1.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_1.paid_at__day AS paid_at__day + , subq_1.paid_at__week AS paid_at__week + , subq_1.paid_at__month AS paid_at__month + , subq_1.paid_at__quarter AS paid_at__quarter + , subq_1.paid_at__year AS paid_at__year + , subq_1.paid_at__extract_year AS paid_at__extract_year + , subq_1.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_1.paid_at__extract_month AS paid_at__extract_month + , subq_1.paid_at__extract_day AS paid_at__extract_day + , subq_1.paid_at__extract_dow AS paid_at__extract_dow + , subq_1.paid_at__extract_doy AS paid_at__extract_doy + , subq_1.booking__ds__day AS booking__ds__day + , subq_1.booking__ds__week AS booking__ds__week + , subq_1.booking__ds__quarter AS booking__ds__quarter + , subq_1.booking__ds__year AS booking__ds__year + , subq_1.booking__ds__extract_year AS booking__ds__extract_year + , subq_1.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_1.booking__ds__extract_month AS booking__ds__extract_month + , subq_1.booking__ds__extract_day AS booking__ds__extract_day + , subq_1.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_1.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day AS booking__paid_at__day + , subq_1.booking__paid_at__week AS booking__paid_at__week + , subq_1.booking__paid_at__month AS booking__paid_at__month + , subq_1.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_1.booking__paid_at__year AS booking__paid_at__year + , subq_1.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_1.metric_time__month AS metric_time__month + , subq_1.metric_time__quarter AS metric_time__quarter + , subq_1.metric_time__year AS metric_time__year + , subq_1.metric_time__extract_year AS metric_time__extract_year + , subq_1.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_1.metric_time__extract_month AS metric_time__extract_month + , subq_1.metric_time__extract_day AS metric_time__extract_day + , subq_1.metric_time__extract_dow AS metric_time__extract_dow + , subq_1.metric_time__extract_doy AS metric_time__extract_doy + , subq_1.listing AS listing + , subq_1.guest AS guest + , subq_1.host AS host + , subq_1.booking__listing AS booking__listing + , subq_1.booking__guest AS booking__guest + , subq_1.booking__host AS booking__host + , subq_1.is_instant AS is_instant + , subq_1.booking__is_instant AS booking__is_instant + , subq_1.bookings AS bookings + , subq_1.instant_bookings AS instant_bookings + , subq_1.booking_value AS booking_value + , subq_1.max_booking_value AS max_booking_value + , subq_1.min_booking_value AS min_booking_value + , subq_1.bookers AS bookers + , subq_1.average_booking_value AS average_booking_value + , subq_1.referred_bookings AS referred_bookings + , subq_1.median_booking_value AS median_booking_value + , subq_1.booking_value_p99 AS booking_value_p99 + , subq_1.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_1.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', subq_3.ds) AS booking__ds__month + , subq_3.ds AS metric_time__day + , DATE_TRUNC('week', subq_3.ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_3 + GROUP BY + DATE_TRUNC('month', subq_3.ds) + , subq_3.ds + , DATE_TRUNC('week', subq_3.ds) + ) subq_2 + INNER JOIN ( + -- 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.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.paid_at__day + , subq_0.paid_at__week + , subq_0.paid_at__month + , subq_0.paid_at__quarter + , subq_0.paid_at__year + , subq_0.paid_at__extract_year + , subq_0.paid_at__extract_quarter + , subq_0.paid_at__extract_month + , subq_0.paid_at__extract_day + , subq_0.paid_at__extract_dow + , subq_0.paid_at__extract_doy + , subq_0.booking__ds__day + , subq_0.booking__ds__week + , subq_0.booking__ds__month + , subq_0.booking__ds__quarter + , subq_0.booking__ds__year + , subq_0.booking__ds__extract_year + , subq_0.booking__ds__extract_quarter + , subq_0.booking__ds__extract_month + , subq_0.booking__ds__extract_day + , subq_0.booking__ds__extract_dow + , subq_0.booking__ds__extract_doy + , subq_0.booking__ds_partitioned__day + , subq_0.booking__ds_partitioned__week + , subq_0.booking__ds_partitioned__month + , subq_0.booking__ds_partitioned__quarter + , subq_0.booking__ds_partitioned__year + , subq_0.booking__ds_partitioned__extract_year + , subq_0.booking__ds_partitioned__extract_quarter + , subq_0.booking__ds_partitioned__extract_month + , subq_0.booking__ds_partitioned__extract_day + , subq_0.booking__ds_partitioned__extract_dow + , subq_0.booking__ds_partitioned__extract_doy + , subq_0.booking__paid_at__day + , subq_0.booking__paid_at__week + , subq_0.booking__paid_at__month + , subq_0.booking__paid_at__quarter + , subq_0.booking__paid_at__year + , subq_0.booking__paid_at__extract_year + , subq_0.booking__paid_at__extract_quarter + , subq_0.booking__paid_at__extract_month + , subq_0.booking__paid_at__extract_day + , subq_0.booking__paid_at__extract_dow + , subq_0.booking__paid_at__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.listing + , subq_0.guest + , subq_0.host + , subq_0.booking__listing + , subq_0.booking__guest + , subq_0.booking__host + , subq_0.is_instant + , subq_0.booking__is_instant + , subq_0.bookings + , subq_0.instant_bookings + , subq_0.booking_value + , subq_0.max_booking_value + , subq_0.min_booking_value + , subq_0.bookers + , subq_0.average_booking_value + , subq_0.referred_bookings + , subq_0.median_booking_value + , subq_0.booking_value_p99 + , subq_0.discrete_booking_value_p99 + , subq_0.approximate_continuous_booking_value_p99 + , subq_0.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_0 + ) subq_1 + ON + ( + subq_1.metric_time__day <= subq_2.metric_time__day + ) AND ( + subq_1.metric_time__day > DATE_ADD('day', -2, subq_2.metric_time__day) + ) + ) subq_4 + ) subq_5 + GROUP BY + subq_5.booking__ds__month + , subq_5.metric_time__day + , subq_5.metric_time__week + ) subq_6 + ON + subq_7.metric_time__day = subq_6.metric_time__day + ) subq_9 + ) subq_10 +) subq_11 +GROUP BY + subq_11.metric_time__week + , subq_11.booking__ds__month + , subq_11.every_two_days_bookers_fill_nulls_with_0 diff --git a/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0_optimized.sql b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0_optimized.sql new file mode 100644 index 0000000000..4057e6b149 --- /dev/null +++ b/tests_metricflow/snapshots/test_cumulative_metric_rendering.py/SqlQueryPlan/Trino/test_window_metric_with_non_default_grains__plan0_optimized.sql @@ -0,0 +1,67 @@ +-- Re-aggregate Metrics via Window Functions +SELECT + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 +FROM ( + -- Compute Metrics via Expressions + SELECT + metric_time__week + , booking__ds__month + , FIRST_VALUE(COALESCE(bookers, 0)) OVER ( + PARTITION BY + metric_time__week + , booking__ds__month + ORDER BY metric_time__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS every_two_days_bookers_fill_nulls_with_0 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_20.ds AS metric_time__day + , DATE_TRUNC('week', subq_20.ds) AS metric_time__week + , subq_18.booking__ds__month AS booking__ds__month + , subq_18.bookers AS bookers + FROM ***************************.mf_time_spine subq_20 + LEFT OUTER JOIN ( + -- Join Self Over Time Range + -- Pass Only Elements: ['bookers', 'metric_time__week', 'booking__ds__month', 'metric_time__day'] + -- Aggregate Measures + SELECT + subq_14.booking__ds__month AS booking__ds__month + , subq_14.metric_time__day AS metric_time__day + , subq_14.metric_time__week AS metric_time__week + , COUNT(DISTINCT bookings_source_src_28000.guest_id) AS bookers + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('month', ds) AS booking__ds__month + , ds AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + FROM ***************************.mf_time_spine subq_15 + GROUP BY + DATE_TRUNC('month', ds) + , ds + , DATE_TRUNC('week', ds) + ) subq_14 + INNER JOIN + ***************************.fct_bookings bookings_source_src_28000 + ON + ( + DATE_TRUNC('day', bookings_source_src_28000.ds) <= subq_14.metric_time__day + ) AND ( + DATE_TRUNC('day', bookings_source_src_28000.ds) > DATE_ADD('day', -2, subq_14.metric_time__day) + ) + GROUP BY + subq_14.booking__ds__month + , subq_14.metric_time__day + , subq_14.metric_time__week + ) subq_18 + ON + subq_20.ds = subq_18.metric_time__day + ) subq_21 +) subq_23 +GROUP BY + metric_time__week + , booking__ds__month + , every_two_days_bookers_fill_nulls_with_0 From 34149aedb75cd1006a72384241a04b885021d322 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 18 Jun 2024 12:54:25 -0700 Subject: [PATCH 26/26] Incorporate default_grain --- .../metricflow_semantics/model/dbt_manifest_parser.py | 2 ++ metricflow/dataflow/builder/dataflow_plan_builder.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/metricflow-semantics/metricflow_semantics/model/dbt_manifest_parser.py b/metricflow-semantics/metricflow_semantics/model/dbt_manifest_parser.py index ea1ba90c9c..7edb9c96c7 100644 --- a/metricflow-semantics/metricflow_semantics/model/dbt_manifest_parser.py +++ b/metricflow-semantics/metricflow_semantics/model/dbt_manifest_parser.py @@ -10,6 +10,7 @@ from dbt_semantic_interfaces.transformations.convert_median import ( ConvertMedianToPercentileRule, ) +from dbt_semantic_interfaces.transformations.default_grain import SetDefaultGrainRule from dbt_semantic_interfaces.transformations.names import LowerCaseNamesRule from dbt_semantic_interfaces.transformations.proxy_measure import CreateProxyMeasureRule from dbt_semantic_interfaces.transformations.semantic_manifest_transformer import ( @@ -35,6 +36,7 @@ def parse_manifest_from_dbt_generated_manifest(manifest_json_string: str) -> Pyd ConvertCountToSumRule(), ConvertMedianToPercentileRule(), DedupeMetricInputMeasuresRule(), # Remove once fix is in core + SetDefaultGrainRule(), ), ) model = PydanticSemanticManifestTransformer.transform(raw_model, rules) diff --git a/metricflow/dataflow/builder/dataflow_plan_builder.py b/metricflow/dataflow/builder/dataflow_plan_builder.py index ef1913c06f..697077d214 100644 --- a/metricflow/dataflow/builder/dataflow_plan_builder.py +++ b/metricflow/dataflow/builder/dataflow_plan_builder.py @@ -420,7 +420,10 @@ def _build_cumulative_metric_output_node( predicate_pushdown_state: PredicatePushdownState, for_group_by_source_node: bool = False, ) -> DataflowPlanNode: - # TODO: replace with default_grain once added to YAML spec + # TODO: use default grain + # What is the expected behavior if you query with default grain? + # What if you query with a grain smaller than default? And larger? + # TODO elsewhere: use default grain for metric_time resolution default_granularity = self._metric_lookup.get_min_queryable_time_granularity(metric_spec.reference) queried_agg_time_dimensions = queried_linkable_specs.included_agg_time_dimension_specs_for_metric(