From 9375eab979aa596bec4c0fa2d96d00b9bf94ec58 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 27 Jan 2025 14:45:44 -0800 Subject: [PATCH] WIP --- .../simple_manifest/metrics.yaml | 10 + .../dataflow/builder/dataflow_plan_builder.py | 29 +- .../dataflow/nodes/join_to_time_spine.py | 9 +- .../query_output/test_offset_metrics.py | 18 +- .../test_custom_granularity.py | 151 +++- ...om_offset_window_time_over_time__plan0.sql | 647 ++++++++++++++++++ ...window_time_over_time__plan0_optimized.sql | 111 +++ ...e_over_time_with_matching_grain__plan0.sql | 604 ++++++++++++++++ ...e_with_matching_grain__plan0_optimized.sql | 86 +++ ...in_where_filter_not_in_group_by__plan0.sql | 476 +++++++++++++ ...ilter_not_in_group_by__plan0_optimized.sql | 62 ++ ...th_where_filter_not_in_group_by__plan0.sql | 529 ++++++++++++++ ...ilter_not_in_group_by__plan0_optimized.sql | 97 +++ ...est_nested_custom_offset_window__plan0.sql | 525 ++++++++++++++ ..._custom_offset_window__plan0_optimized.sql | 161 +++++ ...om_offset_window_matching_grain__plan0.sql | 538 +++++++++++++++ ...window_matching_grain__plan0_optimized.sql | 169 +++++ ...t_window_with_base_grain__query_output.txt | 39 +- ...th_matching_custom_grain__query_output.txt | 8 +- 19 files changed, 4232 insertions(+), 37 deletions(-) create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0_optimized.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0.sql create mode 100644 tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0_optimized.sql diff --git a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml index 4cdad77e57..1d02cf71ad 100644 --- a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml +++ b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml @@ -881,3 +881,13 @@ metric: offset_window: 1 martian_day alias: bookings_offset - name: bookings +--- +metric: + name: bookings_offset_one_martian_day_then_2_martian_days + description: tests a metric with nested custom offset windows + type: derived + type_params: + expr: bookings_offset_one_martian_day + metrics: + - name: bookings_offset_one_martian_day + offset_window: 2 martian_day diff --git a/metricflow/dataflow/builder/dataflow_plan_builder.py b/metricflow/dataflow/builder/dataflow_plan_builder.py index 8b30527631..afac8004d2 100644 --- a/metricflow/dataflow/builder/dataflow_plan_builder.py +++ b/metricflow/dataflow/builder/dataflow_plan_builder.py @@ -1568,7 +1568,10 @@ def _build_time_spine_join_node_for_nested_offset( time_range_constraint: Optional[TimeRangeConstraint], metric_source_node: DataflowPlanNode, ) -> DataflowPlanNode: - # TODO: nested custom offset window plans + # use_offset_custom_granularity_node = self._should_use_offset_custom_granularity_node( + # join_description=before_aggregation_time_spine_join_description, + # queried_agg_time_dimension_specs=queried_agg_time_dimension_specs, + # ) join_spec = self._sort_by_base_granularity(queried_agg_time_dimension_specs)[0] time_spine_node = self._build_time_spine_node( queried_time_spine_specs=queried_agg_time_dimension_specs, @@ -1586,6 +1589,7 @@ def _build_time_spine_join_node_for_nested_offset( ) # TODO: fix bug here where filter specs are being included in when aggregating. + # After that, can this code be combined with basic offset code? if len(metric_spec.filter_spec_set.all_filter_specs) > 0 or time_range_constraint: # FilterElementsNode will only be needed if there are where filter specs that were selected in the group by. specs_in_filters = set( @@ -1646,6 +1650,18 @@ def _build_time_spine_join_node_for_offset( join_type=join_description.join_type, ) + def _should_use_offset_custom_granularity_node( + self, + join_description: Optional[JoinToTimeSpineDescription], + queried_agg_time_dimension_specs: Sequence[TimeDimensionSpec], + ) -> bool: + return bool( + join_description + and join_description.custom_offset_window + and {spec.time_granularity_name for spec in queried_agg_time_dimension_specs} + == {join_description.custom_offset_window.granularity} + ) + def _build_aggregated_measure_from_measure_source_node( self, metric_input_measure_spec: MetricInputMeasureSpec, @@ -1770,11 +1786,9 @@ def _build_aggregated_measure_from_measure_source_node( ) # If querying an offset metric, join to time spine before aggregation. - use_offset_custom_granularity_node = bool( - before_aggregation_time_spine_join_description - and before_aggregation_time_spine_join_description.custom_offset_window - and {spec.time_granularity_name for spec in queried_agg_time_dimension_specs} - == {before_aggregation_time_spine_join_description.custom_offset_window.granularity} + use_offset_custom_granularity_node = self._should_use_offset_custom_granularity_node( + join_description=before_aggregation_time_spine_join_description, + queried_agg_time_dimension_specs=queried_agg_time_dimension_specs, ) if before_aggregation_time_spine_join_description and queried_agg_time_dimension_specs: unaggregated_measure_node = self._build_time_spine_join_node_for_offset( @@ -2013,7 +2027,7 @@ def build_custom_offset_time_spine_node( required_time_spine_specs: Tuple[TimeDimensionSpec, ...], use_offset_custom_granularity_node: bool, ) -> DataflowPlanNode: - """Builds an OffsetByCustomGranularityNode used for custom offset windows.""" + """Builds a time spine node used for custom offset windows.""" time_spine_read_node = self._get_time_spine_read_node_for_custom_grain(offset_window.granularity) if use_offset_custom_granularity_node: return OffsetCustomGranularityNode.create( @@ -2042,6 +2056,7 @@ def _sort_by_base_granularity(self, time_dimension_specs: Sequence[TimeDimension ), ) + # TODO: fix this TODO in other PR # TODO: label this as more specific; not sure yet what it's specific to. def _determine_time_spine_join_spec( self, measure_properties: MeasureSpecProperties, required_time_spine_specs: Tuple[TimeDimensionSpec, ...] diff --git a/metricflow/dataflow/nodes/join_to_time_spine.py b/metricflow/dataflow/nodes/join_to_time_spine.py index 0e8d0a799e..fe6544b33f 100644 --- a/metricflow/dataflow/nodes/join_to_time_spine.py +++ b/metricflow/dataflow/nodes/join_to_time_spine.py @@ -62,6 +62,7 @@ def create( # noqa: D102 offset_to_grain: Optional[TimeGranularity] = None, ) -> JoinToTimeSpineNode: return JoinToTimeSpineNode( + # Note: parent nodes must be in the order of metric_source_node, time_spine_node parent_nodes=(metric_source_node, time_spine_node), metric_source_node=metric_source_node, time_spine_node=time_spine_node, @@ -107,10 +108,12 @@ def functionally_identical(self, other_node: DataflowPlanNode) -> bool: # noqa: ) def with_new_parents(self, new_parent_nodes: Sequence[DataflowPlanNode]) -> JoinToTimeSpineNode: # noqa: D102 - assert len(new_parent_nodes) == 1 + assert len(new_parent_nodes) == 2, "JoinToTimeSpineNode must have exactly 2 parent nodes." + # Note: parent nodes remain in the order of metric_source_node, time_spine_node + return JoinToTimeSpineNode.create( - metric_source_node=self.metric_source_node, - time_spine_node=self.time_spine_node, + metric_source_node=new_parent_nodes[0], + time_spine_node=new_parent_nodes[1], requested_agg_time_dimension_specs=self.requested_agg_time_dimension_specs, standard_offset_window=self.standard_offset_window, offset_to_grain=self.offset_to_grain, diff --git a/tests_metricflow/integration/query_output/test_offset_metrics.py b/tests_metricflow/integration/query_output/test_offset_metrics.py index 12fa3b791c..284a584549 100644 --- a/tests_metricflow/integration/query_output/test_offset_metrics.py +++ b/tests_metricflow/integration/query_output/test_offset_metrics.py @@ -70,10 +70,15 @@ def test_custom_offset_window_with_base_grain( sql_client: SqlClient, it_helpers: IntegrationTestHelpers, ) -> None: - """Gives a side by side comparison of bookings and bookings_offset_one_martian_day.""" + """Gives a side by side comparison of the normal bookings metric with related custom offset metrics, using base grain.""" query_result = it_helpers.mf_engine.query( MetricFlowQueryRequest.create_with_random_request_id( - metric_names=["bookings", "bookings_offset_one_martian_day"], + metric_names=[ + "bookings", + "bookings_offset_one_martian_day", + "bookings_martian_day_over_martian_day", + "bookings_offset_one_martian_day_then_2_martian_days", + ], group_by_names=["metric_time__day", "metric_time__martian_day"], order_by_names=["metric_time__day", "metric_time__martian_day"], ) @@ -129,10 +134,15 @@ def test_custom_offset_window_with_matching_custom_grain( sql_client: SqlClient, it_helpers: IntegrationTestHelpers, ) -> None: - """Gives a side by side comparison of bookings and bookings_offset_one_martian_day.""" + """Gives a side by side comparison of the normal bookings metric with related custom offset metrics, using matching grain.""" query_result = it_helpers.mf_engine.query( MetricFlowQueryRequest.create_with_random_request_id( - metric_names=["bookings", "bookings_offset_one_martian_day"], + metric_names=[ + "bookings", + "bookings_offset_one_martian_day", + "bookings_martian_day_over_martian_day", + # "bookings_offset_one_martian_day_then_2_martian_days", + ], group_by_names=["booking__ds__martian_day", "metric_time__martian_day"], order_by_names=["booking__ds__martian_day", "metric_time__martian_day"], ) diff --git a/tests_metricflow/query_rendering/test_custom_granularity.py b/tests_metricflow/query_rendering/test_custom_granularity.py index 9889abd874..c15adac0e4 100644 --- a/tests_metricflow/query_rendering/test_custom_granularity.py +++ b/tests_metricflow/query_rendering/test_custom_granularity.py @@ -666,6 +666,33 @@ def test_custom_offset_window_with_granularity_and_date_part( # noqa: D103 ) +@pytest.mark.sql_engine_snapshot +def test_custom_offset_window_with_where_filter_not_in_group_by( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_offset_one_martian_day",), + group_by_names=("metric_time__day",), + where_constraints=[ + PydanticWhereFilter(where_sql_template=("{{ TimeDimension('metric_time', 'martian_day') }} = '2020-01-01'")) + ], + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + @pytest.mark.sql_engine_snapshot def test_custom_offset_window_with_only_window_grain( # noqa: D103 request: FixtureRequest, @@ -690,6 +717,124 @@ def test_custom_offset_window_with_only_window_grain( # noqa: D103 ) -# TODO: add more tests -# - with where filter not included in group by -# - nested custom offset +@pytest.mark.sql_engine_snapshot +def test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_offset_one_martian_day",), + group_by_names=("booking__ds__martian_day",), + where_constraints=[ + PydanticWhereFilter(where_sql_template=("{{ TimeDimension('metric_time', 'martian_day') }} = '2020-01-01'")) + ], + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + +@pytest.mark.sql_engine_snapshot +def test_custom_offset_window_time_over_time( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_martian_day_over_martian_day",), + group_by_names=("metric_time__week",), + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + +@pytest.mark.sql_engine_snapshot +def test_custom_offset_window_time_over_time_with_matching_grain( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_martian_day_over_martian_day",), + group_by_names=("metric_time__martian_day",), + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + +@pytest.mark.sql_engine_snapshot +def test_nested_custom_offset_window( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_offset_one_martian_day_then_2_martian_days",), + group_by_names=("metric_time__day",), + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + +@pytest.mark.sql_engine_snapshot +def test_nested_custom_offset_window_matching_grain( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlPlanConverter, + sql_client: SqlClient, + query_parser: MetricFlowQueryParser, +) -> None: + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookings_offset_one_martian_day_then_2_martian_days",), + group_by_names=("metric_time__martian_day",), + ).query_spec + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0.sql new file mode 100644 index 0000000000..cedc49f430 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0.sql @@ -0,0 +1,647 @@ +test_name: test_custom_offset_window_time_over_time +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_20.metric_time__week + , bookings - bookings_offset / NULLIF(bookings_offset, 0) AS bookings_martian_day_over_martian_day +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_15.metric_time__week, subq_19.metric_time__week) AS metric_time__week + , MAX(subq_15.bookings_offset) AS bookings_offset + , MAX(subq_19.bookings) AS bookings + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_14.metric_time__week + , subq_14.bookings AS bookings_offset + FROM ( + -- Aggregate Measures + SELECT + subq_13.metric_time__week + , SUM(subq_13.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__week'] + SELECT + subq_12.metric_time__week + , subq_12.bookings + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_11.metric_time__week AS metric_time__week + , subq_5.ds__day AS ds__day + , subq_5.ds__week AS ds__week + , subq_5.ds__month AS ds__month + , subq_5.ds__quarter AS ds__quarter + , subq_5.ds__year AS ds__year + , subq_5.ds__extract_year AS ds__extract_year + , subq_5.ds__extract_quarter AS ds__extract_quarter + , subq_5.ds__extract_month AS ds__extract_month + , subq_5.ds__extract_day AS ds__extract_day + , subq_5.ds__extract_dow AS ds__extract_dow + , subq_5.ds__extract_doy AS ds__extract_doy + , subq_5.ds_partitioned__day AS ds_partitioned__day + , subq_5.ds_partitioned__week AS ds_partitioned__week + , subq_5.ds_partitioned__month AS ds_partitioned__month + , subq_5.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_5.ds_partitioned__year AS ds_partitioned__year + , subq_5.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_5.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_5.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_5.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_5.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_5.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_5.paid_at__day AS paid_at__day + , subq_5.paid_at__week AS paid_at__week + , subq_5.paid_at__month AS paid_at__month + , subq_5.paid_at__quarter AS paid_at__quarter + , subq_5.paid_at__year AS paid_at__year + , subq_5.paid_at__extract_year AS paid_at__extract_year + , subq_5.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_5.paid_at__extract_month AS paid_at__extract_month + , subq_5.paid_at__extract_day AS paid_at__extract_day + , subq_5.paid_at__extract_dow AS paid_at__extract_dow + , subq_5.paid_at__extract_doy AS paid_at__extract_doy + , subq_5.booking__ds__day AS booking__ds__day + , subq_5.booking__ds__week AS booking__ds__week + , subq_5.booking__ds__month AS booking__ds__month + , subq_5.booking__ds__quarter AS booking__ds__quarter + , subq_5.booking__ds__year AS booking__ds__year + , subq_5.booking__ds__extract_year AS booking__ds__extract_year + , subq_5.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_5.booking__ds__extract_month AS booking__ds__extract_month + , subq_5.booking__ds__extract_day AS booking__ds__extract_day + , subq_5.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_5.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_5.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_5.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_5.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_5.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_5.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_5.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_5.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_5.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_5.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_5.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_5.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_5.booking__paid_at__day AS booking__paid_at__day + , subq_5.booking__paid_at__week AS booking__paid_at__week + , subq_5.booking__paid_at__month AS booking__paid_at__month + , subq_5.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_5.booking__paid_at__year AS booking__paid_at__year + , subq_5.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_5.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_5.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_5.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_5.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_5.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_5.metric_time__month AS metric_time__month + , subq_5.metric_time__quarter AS metric_time__quarter + , subq_5.metric_time__year AS metric_time__year + , subq_5.metric_time__extract_year AS metric_time__extract_year + , subq_5.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_5.metric_time__extract_month AS metric_time__extract_month + , subq_5.metric_time__extract_day AS metric_time__extract_day + , subq_5.metric_time__extract_dow AS metric_time__extract_dow + , subq_5.metric_time__extract_doy AS metric_time__extract_doy + , subq_5.listing AS listing + , subq_5.guest AS guest + , subq_5.host AS host + , subq_5.booking__listing AS booking__listing + , subq_5.booking__guest AS booking__guest + , subq_5.booking__host AS booking__host + , subq_5.is_instant AS is_instant + , subq_5.booking__is_instant AS booking__is_instant + , subq_5.bookings AS bookings + , subq_5.instant_bookings AS instant_bookings + , subq_5.booking_value AS booking_value + , subq_5.max_booking_value AS max_booking_value + , subq_5.min_booking_value AS min_booking_value + , subq_5.bookers AS bookers + , subq_5.average_booking_value AS average_booking_value + , subq_5.referred_bookings AS referred_bookings + , subq_5.median_booking_value AS median_booking_value + , subq_5.booking_value_p99 AS booking_value_p99 + , subq_5.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_5.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_5.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day', 'metric_time__week'] + SELECT + subq_10.ds__day + , subq_10.metric_time__day + , subq_10.metric_time__week + FROM ( + -- Apply Requested Granularities + SELECT + subq_9.ds__day + , subq_9.ds__day__lead AS metric_time__day + , DATE_TRUNC('week', subq_9.ds__day__lead) AS metric_time__week + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_2 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_6.ds__day) OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_6.ds__day) OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_6 + ) + + SELECT + cte_2.ds__day AS ds__day + , CASE + WHEN subq_8.ds__martian_day__first_value__lead + INTERVAL (cte_2.ds__day__row_number - 1) day <= subq_8.ds__martian_day__last_value__lead + THEN subq_8.ds__martian_day__first_value__lead + INTERVAL (cte_2.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_2 cte_2 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_7.ds__martian_day + , LEAD(subq_7.ds__martian_day__first_value, 1) OVER (ORDER BY subq_7.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_7.ds__martian_day__last_value, 1) OVER (ORDER BY subq_7.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_2.ds__martian_day + , cte_2.ds__martian_day__first_value + , cte_2.ds__martian_day__last_value + FROM cte_2 cte_2 + GROUP BY + cte_2.ds__martian_day + , cte_2.ds__martian_day__first_value + , cte_2.ds__martian_day__last_value + ) subq_7 + ) subq_8 + ON + cte_2.ds__martian_day = subq_8.ds__martian_day + ) subq_9 + ) subq_10 + ) subq_11 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.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_4 + ) subq_5 + ON + subq_11.ds__day = subq_5.metric_time__day + ) subq_12 + ) subq_13 + GROUP BY + subq_13.metric_time__week + ) subq_14 + ) subq_15 + FULL OUTER JOIN ( + -- Compute Metrics via Expressions + SELECT + subq_18.metric_time__week + , subq_18.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_17.metric_time__week + , SUM(subq_17.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__week'] + SELECT + subq_16.metric_time__week + , subq_16.bookings + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.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_4 + ) subq_16 + ) subq_17 + GROUP BY + subq_17.metric_time__week + ) subq_18 + ) subq_19 + ON + subq_15.metric_time__week = subq_19.metric_time__week + GROUP BY + COALESCE(subq_15.metric_time__week, subq_19.metric_time__week) +) subq_20 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0_optimized.sql new file mode 100644 index 0000000000..ecf5b42024 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time__plan0_optimized.sql @@ -0,0 +1,111 @@ +test_name: test_custom_offset_window_time_over_time +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +WITH sma_28009_cte AS ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , DATE_TRUNC('week', ds) AS metric_time__week + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 +) + +SELECT + metric_time__week AS metric_time__week + , bookings - bookings_offset / NULLIF(bookings_offset, 0) AS bookings_martian_day_over_martian_day +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_36.metric_time__week, subq_40.metric_time__week) AS metric_time__week + , MAX(subq_36.bookings_offset) AS bookings_offset + , MAX(subq_40.bookings) AS bookings + FROM ( + -- Join to Time Spine Dataset + -- Pass Only Elements: ['bookings', 'metric_time__week'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + DATE_TRUNC('week', subq_30.ds__day__lead) AS metric_time__week + , SUM(sma_28009_cte.bookings) AS bookings_offset + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_7 AS ( + -- Read From Time Spine 'mf_time_spine' + -- Get Custom Granularity Bounds + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + , FIRST_VALUE(ds) OVER ( + PARTITION BY martian_day + ORDER BY ds + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds) OVER ( + PARTITION BY martian_day + ORDER BY ds + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY martian_day + ORDER BY ds + ) AS ds__day__row_number + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_7.ds__day AS ds__day + , CASE + WHEN subq_29.ds__martian_day__first_value__lead + INTERVAL (cte_7.ds__day__row_number - 1) day <= subq_29.ds__martian_day__last_value__lead + THEN subq_29.ds__martian_day__first_value__lead + INTERVAL (cte_7.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_7 cte_7 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_7 cte_7 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_28 + ) subq_29 + ON + cte_7.ds__martian_day = subq_29.ds__martian_day + ) subq_30 + INNER JOIN + sma_28009_cte sma_28009_cte + ON + subq_30.ds__day = sma_28009_cte.metric_time__day + GROUP BY + DATE_TRUNC('week', subq_30.ds__day__lead) + ) subq_36 + FULL OUTER JOIN ( + -- Read From CTE For node_id=sma_28009 + -- Pass Only Elements: ['bookings', 'metric_time__week'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + metric_time__week + , SUM(bookings) AS bookings + FROM sma_28009_cte sma_28009_cte + GROUP BY + metric_time__week + ) subq_40 + ON + subq_36.metric_time__week = subq_40.metric_time__week + GROUP BY + COALESCE(subq_36.metric_time__week, subq_40.metric_time__week) +) subq_41 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0.sql new file mode 100644 index 0000000000..383ef7add8 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0.sql @@ -0,0 +1,604 @@ +test_name: test_custom_offset_window_time_over_time_with_matching_grain +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_15.metric_time__martian_day + , bookings - bookings_offset / NULLIF(bookings_offset, 0) AS bookings_martian_day_over_martian_day +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_9.metric_time__martian_day, subq_14.metric_time__martian_day) AS metric_time__martian_day + , MAX(subq_9.bookings_offset) AS bookings_offset + , MAX(subq_14.bookings) AS bookings + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_8.metric_time__martian_day + , subq_8.bookings AS bookings_offset + FROM ( + -- Aggregate Measures + SELECT + subq_7.metric_time__martian_day + , SUM(subq_7.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__martian_day'] + SELECT + subq_6.metric_time__martian_day + , subq_6.bookings + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_5.metric_time__day AS metric_time__day + , subq_5.metric_time__martian_day AS metric_time__martian_day + , subq_2.ds__day AS ds__day + , subq_2.ds__week AS ds__week + , subq_2.ds__month AS ds__month + , subq_2.ds__quarter AS ds__quarter + , subq_2.ds__year AS ds__year + , subq_2.ds__extract_year AS ds__extract_year + , subq_2.ds__extract_quarter AS ds__extract_quarter + , subq_2.ds__extract_month AS ds__extract_month + , subq_2.ds__extract_day AS ds__extract_day + , subq_2.ds__extract_dow AS ds__extract_dow + , subq_2.ds__extract_doy AS ds__extract_doy + , subq_2.ds_partitioned__day AS ds_partitioned__day + , subq_2.ds_partitioned__week AS ds_partitioned__week + , subq_2.ds_partitioned__month AS ds_partitioned__month + , subq_2.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_2.ds_partitioned__year AS ds_partitioned__year + , subq_2.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_2.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_2.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_2.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_2.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_2.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_2.paid_at__day AS paid_at__day + , subq_2.paid_at__week AS paid_at__week + , subq_2.paid_at__month AS paid_at__month + , subq_2.paid_at__quarter AS paid_at__quarter + , subq_2.paid_at__year AS paid_at__year + , subq_2.paid_at__extract_year AS paid_at__extract_year + , subq_2.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_2.paid_at__extract_month AS paid_at__extract_month + , subq_2.paid_at__extract_day AS paid_at__extract_day + , subq_2.paid_at__extract_dow AS paid_at__extract_dow + , subq_2.paid_at__extract_doy AS paid_at__extract_doy + , subq_2.booking__ds__day AS booking__ds__day + , subq_2.booking__ds__week AS booking__ds__week + , subq_2.booking__ds__month AS booking__ds__month + , subq_2.booking__ds__quarter AS booking__ds__quarter + , subq_2.booking__ds__year AS booking__ds__year + , subq_2.booking__ds__extract_year AS booking__ds__extract_year + , subq_2.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_2.booking__ds__extract_month AS booking__ds__extract_month + , subq_2.booking__ds__extract_day AS booking__ds__extract_day + , subq_2.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_2.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_2.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_2.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_2.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_2.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_2.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_2.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_2.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_2.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_2.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_2.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_2.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_2.booking__paid_at__day AS booking__paid_at__day + , subq_2.booking__paid_at__week AS booking__paid_at__week + , subq_2.booking__paid_at__month AS booking__paid_at__month + , subq_2.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_2.booking__paid_at__year AS booking__paid_at__year + , subq_2.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_2.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_2.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_2.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_2.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_2.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__month AS metric_time__month + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_2.metric_time__year AS metric_time__year + , subq_2.metric_time__extract_year AS metric_time__extract_year + , subq_2.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_2.metric_time__extract_month AS metric_time__extract_month + , subq_2.metric_time__extract_day AS metric_time__extract_day + , subq_2.metric_time__extract_dow AS metric_time__extract_dow + , subq_2.metric_time__extract_doy AS metric_time__extract_doy + , subq_2.listing AS listing + , subq_2.guest AS guest + , subq_2.host AS host + , subq_2.booking__listing AS booking__listing + , subq_2.booking__guest AS booking__guest + , subq_2.booking__host AS booking__host + , subq_2.is_instant AS is_instant + , subq_2.booking__is_instant AS booking__is_instant + , subq_2.bookings AS bookings + , subq_2.instant_bookings AS instant_bookings + , subq_2.booking_value AS booking_value + , subq_2.max_booking_value AS max_booking_value + , subq_2.min_booking_value AS min_booking_value + , subq_2.bookers AS bookers + , subq_2.average_booking_value AS average_booking_value + , subq_2.referred_bookings AS referred_bookings + , subq_2.median_booking_value AS median_booking_value + , subq_2.booking_value_p99 AS booking_value_p99 + , subq_2.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_2.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_2.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day', 'metric_time__martian_day'] + SELECT + subq_4.ds__day + , subq_4.metric_time__day + , subq_4.metric_time__martian_day + FROM ( + -- Join Offset Custom Granularity to Base Granularity + WITH cte_2 AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_2.ds__day AS ds__day + , subq_3.ds__martian_day__lead AS metric_time__day + , subq_3.ds__martian_day__lead AS metric_time__martian_day + FROM cte_2 cte_2 + INNER JOIN ( + -- Offset Custom Granularity + SELECT + cte_2.ds__martian_day + , LEAD(cte_2.ds__martian_day, 1) OVER (ORDER BY cte_2.ds__martian_day) AS ds__martian_day__lead + FROM cte_2 cte_2 + GROUP BY + cte_2.ds__martian_day + ) subq_3 + ON + cte_2.ds__martian_day = subq_3.ds__martian_day + ) subq_4 + ) subq_5 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_1.ds__day + , subq_1.ds__week + , subq_1.ds__month + , subq_1.ds__quarter + , subq_1.ds__year + , subq_1.ds__extract_year + , subq_1.ds__extract_quarter + , subq_1.ds__extract_month + , subq_1.ds__extract_day + , subq_1.ds__extract_dow + , subq_1.ds__extract_doy + , subq_1.ds_partitioned__day + , subq_1.ds_partitioned__week + , subq_1.ds_partitioned__month + , subq_1.ds_partitioned__quarter + , subq_1.ds_partitioned__year + , subq_1.ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy + , subq_1.paid_at__day + , subq_1.paid_at__week + , subq_1.paid_at__month + , subq_1.paid_at__quarter + , subq_1.paid_at__year + , subq_1.paid_at__extract_year + , subq_1.paid_at__extract_quarter + , subq_1.paid_at__extract_month + , subq_1.paid_at__extract_day + , subq_1.paid_at__extract_dow + , subq_1.paid_at__extract_doy + , subq_1.booking__ds__day + , subq_1.booking__ds__week + , subq_1.booking__ds__month + , subq_1.booking__ds__quarter + , subq_1.booking__ds__year + , subq_1.booking__ds__extract_year + , subq_1.booking__ds__extract_quarter + , subq_1.booking__ds__extract_month + , subq_1.booking__ds__extract_day + , subq_1.booking__ds__extract_dow + , subq_1.booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day + , subq_1.booking__paid_at__week + , subq_1.booking__paid_at__month + , subq_1.booking__paid_at__quarter + , subq_1.booking__paid_at__year + , subq_1.booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy + , subq_1.ds__day AS metric_time__day + , subq_1.ds__week AS metric_time__week + , subq_1.ds__month AS metric_time__month + , subq_1.ds__quarter AS metric_time__quarter + , subq_1.ds__year AS metric_time__year + , subq_1.ds__extract_year AS metric_time__extract_year + , subq_1.ds__extract_quarter AS metric_time__extract_quarter + , subq_1.ds__extract_month AS metric_time__extract_month + , subq_1.ds__extract_day AS metric_time__extract_day + , subq_1.ds__extract_dow AS metric_time__extract_dow + , subq_1.ds__extract_doy AS metric_time__extract_doy + , subq_1.listing + , subq_1.guest + , subq_1.host + , subq_1.booking__listing + , subq_1.booking__guest + , subq_1.booking__host + , subq_1.is_instant + , subq_1.booking__is_instant + , subq_1.bookings + , subq_1.instant_bookings + , subq_1.booking_value + , subq_1.max_booking_value + , subq_1.min_booking_value + , subq_1.bookers + , subq_1.average_booking_value + , subq_1.referred_bookings + , subq_1.median_booking_value + , subq_1.booking_value_p99 + , subq_1.discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 + , subq_1.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_1 + ) subq_2 + ON + subq_5.ds__day = subq_2.metric_time__day + ) subq_6 + ) subq_7 + GROUP BY + subq_7.metric_time__martian_day + ) subq_8 + ) subq_9 + FULL OUTER JOIN ( + -- Compute Metrics via Expressions + SELECT + subq_13.metric_time__martian_day + , subq_13.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_12.metric_time__martian_day + , SUM(subq_12.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__martian_day'] + SELECT + subq_11.metric_time__martian_day + , subq_11.bookings + FROM ( + -- Metric Time Dimension 'ds' + -- Join to Custom Granularity Dataset + SELECT + 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__month AS booking__ds__month + , 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.ds__day AS metric_time__day + , subq_1.ds__week AS metric_time__week + , subq_1.ds__month AS metric_time__month + , subq_1.ds__quarter AS metric_time__quarter + , subq_1.ds__year AS metric_time__year + , subq_1.ds__extract_year AS metric_time__extract_year + , subq_1.ds__extract_quarter AS metric_time__extract_quarter + , subq_1.ds__extract_month AS metric_time__extract_month + , subq_1.ds__extract_day AS metric_time__extract_day + , subq_1.ds__extract_dow AS metric_time__extract_dow + , subq_1.ds__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 + , subq_10.martian_day AS metric_time__martian_day + 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_1 + LEFT OUTER JOIN + ***************************.mf_time_spine subq_10 + ON + subq_1.ds__day = subq_10.ds + ) subq_11 + ) subq_12 + GROUP BY + subq_12.metric_time__martian_day + ) subq_13 + ) subq_14 + ON + subq_9.metric_time__martian_day = subq_14.metric_time__martian_day + GROUP BY + COALESCE(subq_9.metric_time__martian_day, subq_14.metric_time__martian_day) +) subq_15 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0_optimized.sql new file mode 100644 index 0000000000..846e87764a --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_time_over_time_with_matching_grain__plan0_optimized.sql @@ -0,0 +1,86 @@ +test_name: test_custom_offset_window_time_over_time_with_matching_grain +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +WITH sma_28009_cte AS ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 +) + +SELECT + metric_time__martian_day AS metric_time__martian_day + , bookings - bookings_offset / NULLIF(bookings_offset, 0) AS bookings_martian_day_over_martian_day +FROM ( + -- Combine Aggregated Outputs + SELECT + COALESCE(subq_25.metric_time__martian_day, subq_30.metric_time__martian_day) AS metric_time__martian_day + , MAX(subq_25.bookings_offset) AS bookings_offset + , MAX(subq_30.bookings) AS bookings + FROM ( + -- Join to Time Spine Dataset + -- Pass Only Elements: ['bookings', 'metric_time__martian_day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_20.metric_time__martian_day AS metric_time__martian_day + , SUM(sma_28009_cte.bookings) AS bookings_offset + FROM ( + -- Join Offset Custom Granularity to Base Granularity + WITH cte_7 AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_7.ds__day AS ds__day + , subq_19.ds__martian_day__lead AS metric_time__martian_day + FROM cte_7 cte_7 + INNER JOIN ( + -- Offset Custom Granularity + SELECT + ds__martian_day + , LEAD(ds__martian_day, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__lead + FROM cte_7 cte_7 + GROUP BY + ds__martian_day + ) subq_19 + ON + cte_7.ds__martian_day = subq_19.ds__martian_day + ) subq_20 + INNER JOIN + sma_28009_cte sma_28009_cte + ON + subq_20.ds__day = sma_28009_cte.metric_time__day + GROUP BY + subq_20.metric_time__martian_day + ) subq_25 + FULL OUTER JOIN ( + -- Read From CTE For node_id=sma_28009 + -- Join to Custom Granularity Dataset + -- Pass Only Elements: ['bookings', 'metric_time__martian_day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_26.martian_day AS metric_time__martian_day + , SUM(sma_28009_cte.bookings) AS bookings + FROM sma_28009_cte sma_28009_cte + LEFT OUTER JOIN + ***************************.mf_time_spine subq_26 + ON + sma_28009_cte.metric_time__day = subq_26.ds + GROUP BY + subq_26.martian_day + ) subq_30 + ON + subq_25.metric_time__martian_day = subq_30.metric_time__martian_day + GROUP BY + COALESCE(subq_25.metric_time__martian_day, subq_30.metric_time__martian_day) +) subq_31 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0.sql new file mode 100644 index 0000000000..e4d7f135e1 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0.sql @@ -0,0 +1,476 @@ +test_name: test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_10.booking__ds__martian_day + , bookings AS bookings_offset_one_martian_day +FROM ( + -- Compute Metrics via Expressions + SELECT + subq_9.booking__ds__martian_day + , subq_9.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_8.booking__ds__martian_day + , SUM(subq_8.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'booking__ds__martian_day'] + SELECT + subq_7.booking__ds__martian_day + , subq_7.bookings + FROM ( + -- Constrain Output with WHERE + SELECT + subq_6.ds__day + , subq_6.ds__week + , subq_6.ds__month + , subq_6.ds__quarter + , subq_6.ds__year + , subq_6.ds__extract_year + , subq_6.ds__extract_quarter + , subq_6.ds__extract_month + , subq_6.ds__extract_day + , subq_6.ds__extract_dow + , subq_6.ds__extract_doy + , subq_6.ds_partitioned__day + , subq_6.ds_partitioned__week + , subq_6.ds_partitioned__month + , subq_6.ds_partitioned__quarter + , subq_6.ds_partitioned__year + , subq_6.ds_partitioned__extract_year + , subq_6.ds_partitioned__extract_quarter + , subq_6.ds_partitioned__extract_month + , subq_6.ds_partitioned__extract_day + , subq_6.ds_partitioned__extract_dow + , subq_6.ds_partitioned__extract_doy + , subq_6.paid_at__day + , subq_6.paid_at__week + , subq_6.paid_at__month + , subq_6.paid_at__quarter + , subq_6.paid_at__year + , subq_6.paid_at__extract_year + , subq_6.paid_at__extract_quarter + , subq_6.paid_at__extract_month + , subq_6.paid_at__extract_day + , subq_6.paid_at__extract_dow + , subq_6.paid_at__extract_doy + , subq_6.booking__ds__week + , subq_6.booking__ds__month + , subq_6.booking__ds__quarter + , subq_6.booking__ds__year + , subq_6.booking__ds__extract_year + , subq_6.booking__ds__extract_quarter + , subq_6.booking__ds__extract_month + , subq_6.booking__ds__extract_day + , subq_6.booking__ds__extract_dow + , subq_6.booking__ds__extract_doy + , subq_6.booking__ds_partitioned__day + , subq_6.booking__ds_partitioned__week + , subq_6.booking__ds_partitioned__month + , subq_6.booking__ds_partitioned__quarter + , subq_6.booking__ds_partitioned__year + , subq_6.booking__ds_partitioned__extract_year + , subq_6.booking__ds_partitioned__extract_quarter + , subq_6.booking__ds_partitioned__extract_month + , subq_6.booking__ds_partitioned__extract_day + , subq_6.booking__ds_partitioned__extract_dow + , subq_6.booking__ds_partitioned__extract_doy + , subq_6.booking__paid_at__day + , subq_6.booking__paid_at__week + , subq_6.booking__paid_at__month + , subq_6.booking__paid_at__quarter + , subq_6.booking__paid_at__year + , subq_6.booking__paid_at__extract_year + , subq_6.booking__paid_at__extract_quarter + , subq_6.booking__paid_at__extract_month + , subq_6.booking__paid_at__extract_day + , subq_6.booking__paid_at__extract_dow + , subq_6.booking__paid_at__extract_doy + , subq_6.metric_time__day + , subq_6.metric_time__week + , subq_6.metric_time__month + , subq_6.metric_time__quarter + , subq_6.metric_time__year + , subq_6.metric_time__extract_year + , subq_6.metric_time__extract_quarter + , subq_6.metric_time__extract_month + , subq_6.metric_time__extract_day + , subq_6.metric_time__extract_dow + , subq_6.metric_time__extract_doy + , subq_6.booking__ds__day + , subq_6.booking__ds__martian_day + , subq_6.listing + , subq_6.guest + , subq_6.host + , subq_6.booking__listing + , subq_6.booking__guest + , subq_6.booking__host + , subq_6.is_instant + , subq_6.booking__is_instant + , subq_6.bookings + , subq_6.instant_bookings + , subq_6.booking_value + , subq_6.max_booking_value + , subq_6.min_booking_value + , subq_6.bookers + , subq_6.average_booking_value + , subq_6.referred_bookings + , subq_6.median_booking_value + , subq_6.booking_value_p99 + , subq_6.discrete_booking_value_p99 + , subq_6.approximate_continuous_booking_value_p99 + , subq_6.approximate_discrete_booking_value_p99 + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_5.booking__ds__day AS booking__ds__day + , subq_5.booking__ds__martian_day AS booking__ds__martian_day + , subq_2.ds__day AS ds__day + , subq_2.ds__week AS ds__week + , subq_2.ds__month AS ds__month + , subq_2.ds__quarter AS ds__quarter + , subq_2.ds__year AS ds__year + , subq_2.ds__extract_year AS ds__extract_year + , subq_2.ds__extract_quarter AS ds__extract_quarter + , subq_2.ds__extract_month AS ds__extract_month + , subq_2.ds__extract_day AS ds__extract_day + , subq_2.ds__extract_dow AS ds__extract_dow + , subq_2.ds__extract_doy AS ds__extract_doy + , subq_2.ds_partitioned__day AS ds_partitioned__day + , subq_2.ds_partitioned__week AS ds_partitioned__week + , subq_2.ds_partitioned__month AS ds_partitioned__month + , subq_2.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_2.ds_partitioned__year AS ds_partitioned__year + , subq_2.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_2.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_2.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_2.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_2.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_2.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_2.paid_at__day AS paid_at__day + , subq_2.paid_at__week AS paid_at__week + , subq_2.paid_at__month AS paid_at__month + , subq_2.paid_at__quarter AS paid_at__quarter + , subq_2.paid_at__year AS paid_at__year + , subq_2.paid_at__extract_year AS paid_at__extract_year + , subq_2.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_2.paid_at__extract_month AS paid_at__extract_month + , subq_2.paid_at__extract_day AS paid_at__extract_day + , subq_2.paid_at__extract_dow AS paid_at__extract_dow + , subq_2.paid_at__extract_doy AS paid_at__extract_doy + , subq_2.booking__ds__week AS booking__ds__week + , subq_2.booking__ds__month AS booking__ds__month + , subq_2.booking__ds__quarter AS booking__ds__quarter + , subq_2.booking__ds__year AS booking__ds__year + , subq_2.booking__ds__extract_year AS booking__ds__extract_year + , subq_2.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_2.booking__ds__extract_month AS booking__ds__extract_month + , subq_2.booking__ds__extract_day AS booking__ds__extract_day + , subq_2.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_2.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_2.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_2.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_2.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_2.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_2.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_2.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_2.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_2.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_2.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_2.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_2.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_2.booking__paid_at__day AS booking__paid_at__day + , subq_2.booking__paid_at__week AS booking__paid_at__week + , subq_2.booking__paid_at__month AS booking__paid_at__month + , subq_2.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_2.booking__paid_at__year AS booking__paid_at__year + , subq_2.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_2.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_2.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_2.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_2.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_2.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_2.metric_time__day AS metric_time__day + , subq_2.metric_time__week AS metric_time__week + , subq_2.metric_time__month AS metric_time__month + , subq_2.metric_time__quarter AS metric_time__quarter + , subq_2.metric_time__year AS metric_time__year + , subq_2.metric_time__extract_year AS metric_time__extract_year + , subq_2.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_2.metric_time__extract_month AS metric_time__extract_month + , subq_2.metric_time__extract_day AS metric_time__extract_day + , subq_2.metric_time__extract_dow AS metric_time__extract_dow + , subq_2.metric_time__extract_doy AS metric_time__extract_doy + , subq_2.listing AS listing + , subq_2.guest AS guest + , subq_2.host AS host + , subq_2.booking__listing AS booking__listing + , subq_2.booking__guest AS booking__guest + , subq_2.booking__host AS booking__host + , subq_2.is_instant AS is_instant + , subq_2.booking__is_instant AS booking__is_instant + , subq_2.bookings AS bookings + , subq_2.instant_bookings AS instant_bookings + , subq_2.booking_value AS booking_value + , subq_2.max_booking_value AS max_booking_value + , subq_2.min_booking_value AS min_booking_value + , subq_2.bookers AS bookers + , subq_2.average_booking_value AS average_booking_value + , subq_2.referred_bookings AS referred_bookings + , subq_2.median_booking_value AS median_booking_value + , subq_2.booking_value_p99 AS booking_value_p99 + , subq_2.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_2.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_2.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Pass Only Elements: ['ds__day', 'booking__ds__day', 'booking__ds__martian_day'] + SELECT + subq_4.ds__day + , subq_4.booking__ds__day + , subq_4.booking__ds__martian_day + FROM ( + -- Join Offset Custom Granularity to Base Granularity + WITH cte_2 AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_2.ds__day AS ds__day + , subq_3.ds__martian_day__lead AS booking__ds__day + , subq_3.ds__martian_day__lead AS booking__ds__martian_day + FROM cte_2 cte_2 + INNER JOIN ( + -- Offset Custom Granularity + SELECT + cte_2.ds__martian_day + , LEAD(cte_2.ds__martian_day, 1) OVER (ORDER BY cte_2.ds__martian_day) AS ds__martian_day__lead + FROM cte_2 cte_2 + GROUP BY + cte_2.ds__martian_day + ) subq_3 + ON + cte_2.ds__martian_day = subq_3.ds__martian_day + ) subq_4 + ) subq_5 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_1.ds__day + , subq_1.ds__week + , subq_1.ds__month + , subq_1.ds__quarter + , subq_1.ds__year + , subq_1.ds__extract_year + , subq_1.ds__extract_quarter + , subq_1.ds__extract_month + , subq_1.ds__extract_day + , subq_1.ds__extract_dow + , subq_1.ds__extract_doy + , subq_1.ds_partitioned__day + , subq_1.ds_partitioned__week + , subq_1.ds_partitioned__month + , subq_1.ds_partitioned__quarter + , subq_1.ds_partitioned__year + , subq_1.ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy + , subq_1.paid_at__day + , subq_1.paid_at__week + , subq_1.paid_at__month + , subq_1.paid_at__quarter + , subq_1.paid_at__year + , subq_1.paid_at__extract_year + , subq_1.paid_at__extract_quarter + , subq_1.paid_at__extract_month + , subq_1.paid_at__extract_day + , subq_1.paid_at__extract_dow + , subq_1.paid_at__extract_doy + , subq_1.booking__ds__day + , subq_1.booking__ds__week + , subq_1.booking__ds__month + , subq_1.booking__ds__quarter + , subq_1.booking__ds__year + , subq_1.booking__ds__extract_year + , subq_1.booking__ds__extract_quarter + , subq_1.booking__ds__extract_month + , subq_1.booking__ds__extract_day + , subq_1.booking__ds__extract_dow + , subq_1.booking__ds__extract_doy + , subq_1.booking__ds_partitioned__day + , subq_1.booking__ds_partitioned__week + , subq_1.booking__ds_partitioned__month + , subq_1.booking__ds_partitioned__quarter + , subq_1.booking__ds_partitioned__year + , subq_1.booking__ds_partitioned__extract_year + , subq_1.booking__ds_partitioned__extract_quarter + , subq_1.booking__ds_partitioned__extract_month + , subq_1.booking__ds_partitioned__extract_day + , subq_1.booking__ds_partitioned__extract_dow + , subq_1.booking__ds_partitioned__extract_doy + , subq_1.booking__paid_at__day + , subq_1.booking__paid_at__week + , subq_1.booking__paid_at__month + , subq_1.booking__paid_at__quarter + , subq_1.booking__paid_at__year + , subq_1.booking__paid_at__extract_year + , subq_1.booking__paid_at__extract_quarter + , subq_1.booking__paid_at__extract_month + , subq_1.booking__paid_at__extract_day + , subq_1.booking__paid_at__extract_dow + , subq_1.booking__paid_at__extract_doy + , subq_1.ds__day AS metric_time__day + , subq_1.ds__week AS metric_time__week + , subq_1.ds__month AS metric_time__month + , subq_1.ds__quarter AS metric_time__quarter + , subq_1.ds__year AS metric_time__year + , subq_1.ds__extract_year AS metric_time__extract_year + , subq_1.ds__extract_quarter AS metric_time__extract_quarter + , subq_1.ds__extract_month AS metric_time__extract_month + , subq_1.ds__extract_day AS metric_time__extract_day + , subq_1.ds__extract_dow AS metric_time__extract_dow + , subq_1.ds__extract_doy AS metric_time__extract_doy + , subq_1.listing + , subq_1.guest + , subq_1.host + , subq_1.booking__listing + , subq_1.booking__guest + , subq_1.booking__host + , subq_1.is_instant + , subq_1.booking__is_instant + , subq_1.bookings + , subq_1.instant_bookings + , subq_1.booking_value + , subq_1.max_booking_value + , subq_1.min_booking_value + , subq_1.bookers + , subq_1.average_booking_value + , subq_1.referred_bookings + , subq_1.median_booking_value + , subq_1.booking_value_p99 + , subq_1.discrete_booking_value_p99 + , subq_1.approximate_continuous_booking_value_p99 + , subq_1.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_1 + ) subq_2 + ON + subq_5.ds__day = subq_2.booking__ds__day + ) subq_6 + WHERE metric_time__martian_day = '2020-01-01' + ) subq_7 + ) subq_8 + GROUP BY + subq_8.booking__ds__martian_day + ) subq_9 +) subq_10 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0_optimized.sql new file mode 100644 index 0000000000..37425ed51f --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by__plan0_optimized.sql @@ -0,0 +1,62 @@ +test_name: test_custom_offset_window_with_matching_grain_where_filter_not_in_group_by +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + booking__ds__martian_day + , bookings AS bookings_offset_one_martian_day +FROM ( + -- Constrain Output with WHERE + -- Pass Only Elements: ['bookings', 'booking__ds__martian_day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + booking__ds__martian_day + , SUM(bookings) AS bookings + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_15.booking__ds__martian_day AS booking__ds__martian_day + , subq_13.bookings AS bookings + FROM ( + -- Join Offset Custom Granularity to Base Granularity + WITH cte_6 AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_6.ds__day AS ds__day + , subq_14.ds__martian_day__lead AS booking__ds__martian_day + FROM cte_6 cte_6 + INNER JOIN ( + -- Offset Custom Granularity + SELECT + ds__martian_day + , LEAD(ds__martian_day, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__lead + FROM cte_6 cte_6 + GROUP BY + ds__martian_day + ) subq_14 + ON + cte_6.ds__martian_day = subq_14.ds__martian_day + ) subq_15 + INNER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS booking__ds__day + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_13 + ON + subq_15.ds__day = subq_13.booking__ds__day + ) subq_17 + WHERE metric_time__martian_day = '2020-01-01' + GROUP BY + booking__ds__martian_day +) subq_21 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0.sql new file mode 100644 index 0000000000..a4e1f70656 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0.sql @@ -0,0 +1,529 @@ +test_name: test_custom_offset_window_with_where_filter_not_in_group_by +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_17.metric_time__day + , bookings AS bookings_offset_one_martian_day +FROM ( + -- Compute Metrics via Expressions + SELECT + subq_16.metric_time__day + , subq_16.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_15.metric_time__day + , SUM(subq_15.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__day'] + SELECT + subq_14.metric_time__day + , subq_14.bookings + FROM ( + -- Constrain Output with WHERE + SELECT + subq_13.metric_time__martian_day + , subq_13.ds__day + , subq_13.ds__week + , subq_13.ds__month + , subq_13.ds__quarter + , subq_13.ds__year + , subq_13.ds__extract_year + , subq_13.ds__extract_quarter + , subq_13.ds__extract_month + , subq_13.ds__extract_day + , subq_13.ds__extract_dow + , subq_13.ds__extract_doy + , subq_13.ds_partitioned__day + , subq_13.ds_partitioned__week + , subq_13.ds_partitioned__month + , subq_13.ds_partitioned__quarter + , subq_13.ds_partitioned__year + , subq_13.ds_partitioned__extract_year + , subq_13.ds_partitioned__extract_quarter + , subq_13.ds_partitioned__extract_month + , subq_13.ds_partitioned__extract_day + , subq_13.ds_partitioned__extract_dow + , subq_13.ds_partitioned__extract_doy + , subq_13.paid_at__day + , subq_13.paid_at__week + , subq_13.paid_at__month + , subq_13.paid_at__quarter + , subq_13.paid_at__year + , subq_13.paid_at__extract_year + , subq_13.paid_at__extract_quarter + , subq_13.paid_at__extract_month + , subq_13.paid_at__extract_day + , subq_13.paid_at__extract_dow + , subq_13.paid_at__extract_doy + , subq_13.booking__ds__day + , subq_13.booking__ds__week + , subq_13.booking__ds__month + , subq_13.booking__ds__quarter + , subq_13.booking__ds__year + , subq_13.booking__ds__extract_year + , subq_13.booking__ds__extract_quarter + , subq_13.booking__ds__extract_month + , subq_13.booking__ds__extract_day + , subq_13.booking__ds__extract_dow + , subq_13.booking__ds__extract_doy + , subq_13.booking__ds_partitioned__day + , subq_13.booking__ds_partitioned__week + , subq_13.booking__ds_partitioned__month + , subq_13.booking__ds_partitioned__quarter + , subq_13.booking__ds_partitioned__year + , subq_13.booking__ds_partitioned__extract_year + , subq_13.booking__ds_partitioned__extract_quarter + , subq_13.booking__ds_partitioned__extract_month + , subq_13.booking__ds_partitioned__extract_day + , subq_13.booking__ds_partitioned__extract_dow + , subq_13.booking__ds_partitioned__extract_doy + , subq_13.booking__paid_at__day + , subq_13.booking__paid_at__week + , subq_13.booking__paid_at__month + , subq_13.booking__paid_at__quarter + , subq_13.booking__paid_at__year + , subq_13.booking__paid_at__extract_year + , subq_13.booking__paid_at__extract_quarter + , subq_13.booking__paid_at__extract_month + , subq_13.booking__paid_at__extract_day + , subq_13.booking__paid_at__extract_dow + , subq_13.booking__paid_at__extract_doy + , subq_13.metric_time__week + , subq_13.metric_time__month + , subq_13.metric_time__quarter + , subq_13.metric_time__year + , subq_13.metric_time__extract_year + , subq_13.metric_time__extract_quarter + , subq_13.metric_time__extract_month + , subq_13.metric_time__extract_day + , subq_13.metric_time__extract_dow + , subq_13.metric_time__extract_doy + , subq_13.metric_time__day + , subq_13.listing + , subq_13.guest + , subq_13.host + , subq_13.booking__listing + , subq_13.booking__guest + , subq_13.booking__host + , subq_13.is_instant + , subq_13.booking__is_instant + , subq_13.bookings + , subq_13.instant_bookings + , subq_13.booking_value + , subq_13.max_booking_value + , subq_13.min_booking_value + , subq_13.bookers + , subq_13.average_booking_value + , subq_13.referred_bookings + , subq_13.median_booking_value + , subq_13.booking_value_p99 + , subq_13.discrete_booking_value_p99 + , subq_13.approximate_continuous_booking_value_p99 + , subq_13.approximate_discrete_booking_value_p99 + FROM ( + -- Join to Time Spine Dataset + -- Join to Custom Granularity Dataset + SELECT + subq_11.metric_time__day AS metric_time__day + , subq_5.ds__day AS ds__day + , subq_5.ds__week AS ds__week + , subq_5.ds__month AS ds__month + , subq_5.ds__quarter AS ds__quarter + , subq_5.ds__year AS ds__year + , subq_5.ds__extract_year AS ds__extract_year + , subq_5.ds__extract_quarter AS ds__extract_quarter + , subq_5.ds__extract_month AS ds__extract_month + , subq_5.ds__extract_day AS ds__extract_day + , subq_5.ds__extract_dow AS ds__extract_dow + , subq_5.ds__extract_doy AS ds__extract_doy + , subq_5.ds_partitioned__day AS ds_partitioned__day + , subq_5.ds_partitioned__week AS ds_partitioned__week + , subq_5.ds_partitioned__month AS ds_partitioned__month + , subq_5.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_5.ds_partitioned__year AS ds_partitioned__year + , subq_5.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_5.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_5.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_5.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_5.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_5.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_5.paid_at__day AS paid_at__day + , subq_5.paid_at__week AS paid_at__week + , subq_5.paid_at__month AS paid_at__month + , subq_5.paid_at__quarter AS paid_at__quarter + , subq_5.paid_at__year AS paid_at__year + , subq_5.paid_at__extract_year AS paid_at__extract_year + , subq_5.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_5.paid_at__extract_month AS paid_at__extract_month + , subq_5.paid_at__extract_day AS paid_at__extract_day + , subq_5.paid_at__extract_dow AS paid_at__extract_dow + , subq_5.paid_at__extract_doy AS paid_at__extract_doy + , subq_5.booking__ds__day AS booking__ds__day + , subq_5.booking__ds__week AS booking__ds__week + , subq_5.booking__ds__month AS booking__ds__month + , subq_5.booking__ds__quarter AS booking__ds__quarter + , subq_5.booking__ds__year AS booking__ds__year + , subq_5.booking__ds__extract_year AS booking__ds__extract_year + , subq_5.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_5.booking__ds__extract_month AS booking__ds__extract_month + , subq_5.booking__ds__extract_day AS booking__ds__extract_day + , subq_5.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_5.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_5.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_5.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_5.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_5.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_5.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_5.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_5.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_5.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_5.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_5.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_5.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_5.booking__paid_at__day AS booking__paid_at__day + , subq_5.booking__paid_at__week AS booking__paid_at__week + , subq_5.booking__paid_at__month AS booking__paid_at__month + , subq_5.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_5.booking__paid_at__year AS booking__paid_at__year + , subq_5.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_5.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_5.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_5.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_5.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_5.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_5.metric_time__week AS metric_time__week + , subq_5.metric_time__month AS metric_time__month + , subq_5.metric_time__quarter AS metric_time__quarter + , subq_5.metric_time__year AS metric_time__year + , subq_5.metric_time__extract_year AS metric_time__extract_year + , subq_5.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_5.metric_time__extract_month AS metric_time__extract_month + , subq_5.metric_time__extract_day AS metric_time__extract_day + , subq_5.metric_time__extract_dow AS metric_time__extract_dow + , subq_5.metric_time__extract_doy AS metric_time__extract_doy + , subq_5.listing AS listing + , subq_5.guest AS guest + , subq_5.host AS host + , subq_5.booking__listing AS booking__listing + , subq_5.booking__guest AS booking__guest + , subq_5.booking__host AS booking__host + , subq_5.is_instant AS is_instant + , subq_5.booking__is_instant AS booking__is_instant + , subq_5.bookings AS bookings + , subq_5.instant_bookings AS instant_bookings + , subq_5.booking_value AS booking_value + , subq_5.max_booking_value AS max_booking_value + , subq_5.min_booking_value AS min_booking_value + , subq_5.bookers AS bookers + , subq_5.average_booking_value AS average_booking_value + , subq_5.referred_bookings AS referred_bookings + , subq_5.median_booking_value AS median_booking_value + , subq_5.booking_value_p99 AS booking_value_p99 + , subq_5.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_5.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_5.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + , subq_12.martian_day AS metric_time__martian_day + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day'] + SELECT + subq_10.ds__day + , subq_10.metric_time__day + FROM ( + -- Apply Requested Granularities + SELECT + subq_9.ds__day + , subq_9.ds__day__lead AS metric_time__day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_2 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_6.ds__day) OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_6.ds__day) OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_6.ds__martian_day + ORDER BY subq_6.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_6 + ) + + SELECT + cte_2.ds__day AS ds__day + , CASE + WHEN subq_8.ds__martian_day__first_value__lead + INTERVAL (cte_2.ds__day__row_number - 1) day <= subq_8.ds__martian_day__last_value__lead + THEN subq_8.ds__martian_day__first_value__lead + INTERVAL (cte_2.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_2 cte_2 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_7.ds__martian_day + , LEAD(subq_7.ds__martian_day__first_value, 1) OVER (ORDER BY subq_7.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_7.ds__martian_day__last_value, 1) OVER (ORDER BY subq_7.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_2.ds__martian_day + , cte_2.ds__martian_day__first_value + , cte_2.ds__martian_day__last_value + FROM cte_2 cte_2 + GROUP BY + cte_2.ds__martian_day + , cte_2.ds__martian_day__first_value + , cte_2.ds__martian_day__last_value + ) subq_7 + ) subq_8 + ON + cte_2.ds__martian_day = subq_8.ds__martian_day + ) subq_9 + ) subq_10 + ) subq_11 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.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_4 + ) subq_5 + ON + subq_11.ds__day = subq_5.metric_time__day + LEFT OUTER JOIN + ***************************.mf_time_spine subq_12 + ON + subq_11.metric_time__day = subq_12.ds + ) subq_13 + WHERE metric_time__martian_day = '2020-01-01' + ) subq_14 + ) subq_15 + GROUP BY + subq_15.metric_time__day + ) subq_16 +) subq_17 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0_optimized.sql new file mode 100644 index 0000000000..2042687764 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_custom_offset_window_with_where_filter_not_in_group_by__plan0_optimized.sql @@ -0,0 +1,97 @@ +test_name: test_custom_offset_window_with_where_filter_not_in_group_by +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + metric_time__day + , bookings AS bookings_offset_one_martian_day +FROM ( + -- Constrain Output with WHERE + -- Pass Only Elements: ['bookings', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + metric_time__day + , SUM(bookings) AS bookings + FROM ( + -- Join to Time Spine Dataset + -- Join to Custom Granularity Dataset + SELECT + subq_27.ds__day__lead AS metric_time__day + , subq_23.bookings AS bookings + , subq_30.martian_day AS metric_time__martian_day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_6 AS ( + -- Read From Time Spine 'mf_time_spine' + -- Get Custom Granularity Bounds + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + , FIRST_VALUE(ds) OVER ( + PARTITION BY martian_day + ORDER BY ds + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds) OVER ( + PARTITION BY martian_day + ORDER BY ds + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY martian_day + ORDER BY ds + ) AS ds__day__row_number + FROM ***************************.mf_time_spine time_spine_src_28006 + ) + + SELECT + cte_6.ds__day AS ds__day + , CASE + WHEN subq_26.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day <= subq_26.ds__martian_day__last_value__lead + THEN subq_26.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_6 cte_6 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_6 cte_6 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_25 + ) subq_26 + ON + cte_6.ds__martian_day = subq_26.ds__martian_day + ) subq_27 + INNER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_23 + ON + subq_27.ds__day = subq_23.metric_time__day + LEFT OUTER JOIN + ***************************.mf_time_spine subq_30 + ON + subq_27.ds__day__lead = subq_30.ds + ) subq_31 + WHERE metric_time__martian_day = '2020-01-01' + GROUP BY + metric_time__day +) subq_35 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0.sql new file mode 100644 index 0000000000..84fee3cc1e --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0.sql @@ -0,0 +1,525 @@ +test_name: test_nested_custom_offset_window +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_27.metric_time__day + , bookings_offset_one_martian_day AS bookings_offset_one_martian_day_then_2_martian_days +FROM ( + -- Join to Time Spine Dataset + SELECT + subq_26.metric_time__day AS metric_time__day + , subq_20.bookings_offset_one_martian_day AS bookings_offset_one_martian_day + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day'] + SELECT + subq_25.ds__day + , subq_25.metric_time__day + FROM ( + -- Apply Requested Granularities + SELECT + subq_24.ds__day + , subq_24.ds__day__lead AS metric_time__day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_6 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_21.ds__day) OVER ( + PARTITION BY subq_21.ds__martian_day + ORDER BY subq_21.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_21.ds__day) OVER ( + PARTITION BY subq_21.ds__martian_day + ORDER BY subq_21.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_21.ds__martian_day + ORDER BY subq_21.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_21 + ) + + SELECT + cte_6.ds__day AS ds__day + , CASE + WHEN subq_23.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day <= subq_23.ds__martian_day__last_value__lead + THEN subq_23.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_6 cte_6 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_22.ds__martian_day + , LEAD(subq_22.ds__martian_day__first_value, 2) OVER (ORDER BY subq_22.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_22.ds__martian_day__last_value, 2) OVER (ORDER BY subq_22.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_6.ds__martian_day + , cte_6.ds__martian_day__first_value + , cte_6.ds__martian_day__last_value + FROM cte_6 cte_6 + GROUP BY + cte_6.ds__martian_day + , cte_6.ds__martian_day__first_value + , cte_6.ds__martian_day__last_value + ) subq_22 + ) subq_23 + ON + cte_6.ds__martian_day = subq_23.ds__martian_day + ) subq_24 + ) subq_25 + ) subq_26 + INNER JOIN ( + -- Compute Metrics via Expressions + SELECT + subq_19.metric_time__day + , bookings AS bookings_offset_one_martian_day + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_18.metric_time__day + , subq_18.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_17.metric_time__day + , SUM(subq_17.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__day'] + SELECT + subq_16.metric_time__day + , subq_16.bookings + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_15.metric_time__day AS metric_time__day + , subq_9.ds__day AS ds__day + , subq_9.ds__week AS ds__week + , subq_9.ds__month AS ds__month + , subq_9.ds__quarter AS ds__quarter + , subq_9.ds__year AS ds__year + , subq_9.ds__extract_year AS ds__extract_year + , subq_9.ds__extract_quarter AS ds__extract_quarter + , subq_9.ds__extract_month AS ds__extract_month + , subq_9.ds__extract_day AS ds__extract_day + , subq_9.ds__extract_dow AS ds__extract_dow + , subq_9.ds__extract_doy AS ds__extract_doy + , subq_9.ds_partitioned__day AS ds_partitioned__day + , subq_9.ds_partitioned__week AS ds_partitioned__week + , subq_9.ds_partitioned__month AS ds_partitioned__month + , subq_9.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_9.ds_partitioned__year AS ds_partitioned__year + , subq_9.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_9.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_9.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_9.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_9.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_9.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_9.paid_at__day AS paid_at__day + , subq_9.paid_at__week AS paid_at__week + , subq_9.paid_at__month AS paid_at__month + , subq_9.paid_at__quarter AS paid_at__quarter + , subq_9.paid_at__year AS paid_at__year + , subq_9.paid_at__extract_year AS paid_at__extract_year + , subq_9.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_9.paid_at__extract_month AS paid_at__extract_month + , subq_9.paid_at__extract_day AS paid_at__extract_day + , subq_9.paid_at__extract_dow AS paid_at__extract_dow + , subq_9.paid_at__extract_doy AS paid_at__extract_doy + , subq_9.booking__ds__day AS booking__ds__day + , subq_9.booking__ds__week AS booking__ds__week + , subq_9.booking__ds__month AS booking__ds__month + , subq_9.booking__ds__quarter AS booking__ds__quarter + , subq_9.booking__ds__year AS booking__ds__year + , subq_9.booking__ds__extract_year AS booking__ds__extract_year + , subq_9.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_9.booking__ds__extract_month AS booking__ds__extract_month + , subq_9.booking__ds__extract_day AS booking__ds__extract_day + , subq_9.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_9.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_9.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_9.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_9.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_9.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_9.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_9.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_9.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_9.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_9.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_9.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_9.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_9.booking__paid_at__day AS booking__paid_at__day + , subq_9.booking__paid_at__week AS booking__paid_at__week + , subq_9.booking__paid_at__month AS booking__paid_at__month + , subq_9.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_9.booking__paid_at__year AS booking__paid_at__year + , subq_9.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_9.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_9.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_9.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_9.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_9.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_9.metric_time__week AS metric_time__week + , subq_9.metric_time__month AS metric_time__month + , subq_9.metric_time__quarter AS metric_time__quarter + , subq_9.metric_time__year AS metric_time__year + , subq_9.metric_time__extract_year AS metric_time__extract_year + , subq_9.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_9.metric_time__extract_month AS metric_time__extract_month + , subq_9.metric_time__extract_day AS metric_time__extract_day + , subq_9.metric_time__extract_dow AS metric_time__extract_dow + , subq_9.metric_time__extract_doy AS metric_time__extract_doy + , subq_9.listing AS listing + , subq_9.guest AS guest + , subq_9.host AS host + , subq_9.booking__listing AS booking__listing + , subq_9.booking__guest AS booking__guest + , subq_9.booking__host AS booking__host + , subq_9.is_instant AS is_instant + , subq_9.booking__is_instant AS booking__is_instant + , subq_9.bookings AS bookings + , subq_9.instant_bookings AS instant_bookings + , subq_9.booking_value AS booking_value + , subq_9.max_booking_value AS max_booking_value + , subq_9.min_booking_value AS min_booking_value + , subq_9.bookers AS bookers + , subq_9.average_booking_value AS average_booking_value + , subq_9.referred_bookings AS referred_bookings + , subq_9.median_booking_value AS median_booking_value + , subq_9.booking_value_p99 AS booking_value_p99 + , subq_9.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_9.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_9.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day'] + SELECT + subq_14.ds__day + , subq_14.metric_time__day + FROM ( + -- Apply Requested Granularities + SELECT + subq_13.ds__day + , subq_13.ds__day__lead AS metric_time__day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_4 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_10.ds__day) OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_10.ds__day) OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_10 + ) + + SELECT + cte_4.ds__day AS ds__day + , CASE + WHEN subq_12.ds__martian_day__first_value__lead + INTERVAL (cte_4.ds__day__row_number - 1) day <= subq_12.ds__martian_day__last_value__lead + THEN subq_12.ds__martian_day__first_value__lead + INTERVAL (cte_4.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_4 cte_4 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_11.ds__martian_day + , LEAD(subq_11.ds__martian_day__first_value, 1) OVER (ORDER BY subq_11.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_11.ds__martian_day__last_value, 1) OVER (ORDER BY subq_11.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_4.ds__martian_day + , cte_4.ds__martian_day__first_value + , cte_4.ds__martian_day__last_value + FROM cte_4 cte_4 + GROUP BY + cte_4.ds__martian_day + , cte_4.ds__martian_day__first_value + , cte_4.ds__martian_day__last_value + ) subq_11 + ) subq_12 + ON + cte_4.ds__martian_day = subq_12.ds__martian_day + ) subq_13 + ) subq_14 + ) subq_15 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.ds_partitioned__day + , subq_8.ds_partitioned__week + , subq_8.ds_partitioned__month + , subq_8.ds_partitioned__quarter + , subq_8.ds_partitioned__year + , subq_8.ds_partitioned__extract_year + , subq_8.ds_partitioned__extract_quarter + , subq_8.ds_partitioned__extract_month + , subq_8.ds_partitioned__extract_day + , subq_8.ds_partitioned__extract_dow + , subq_8.ds_partitioned__extract_doy + , subq_8.paid_at__day + , subq_8.paid_at__week + , subq_8.paid_at__month + , subq_8.paid_at__quarter + , subq_8.paid_at__year + , subq_8.paid_at__extract_year + , subq_8.paid_at__extract_quarter + , subq_8.paid_at__extract_month + , subq_8.paid_at__extract_day + , subq_8.paid_at__extract_dow + , subq_8.paid_at__extract_doy + , subq_8.booking__ds__day + , subq_8.booking__ds__week + , subq_8.booking__ds__month + , subq_8.booking__ds__quarter + , subq_8.booking__ds__year + , subq_8.booking__ds__extract_year + , subq_8.booking__ds__extract_quarter + , subq_8.booking__ds__extract_month + , subq_8.booking__ds__extract_day + , subq_8.booking__ds__extract_dow + , subq_8.booking__ds__extract_doy + , subq_8.booking__ds_partitioned__day + , subq_8.booking__ds_partitioned__week + , subq_8.booking__ds_partitioned__month + , subq_8.booking__ds_partitioned__quarter + , subq_8.booking__ds_partitioned__year + , subq_8.booking__ds_partitioned__extract_year + , subq_8.booking__ds_partitioned__extract_quarter + , subq_8.booking__ds_partitioned__extract_month + , subq_8.booking__ds_partitioned__extract_day + , subq_8.booking__ds_partitioned__extract_dow + , subq_8.booking__ds_partitioned__extract_doy + , subq_8.booking__paid_at__day + , subq_8.booking__paid_at__week + , subq_8.booking__paid_at__month + , subq_8.booking__paid_at__quarter + , subq_8.booking__paid_at__year + , subq_8.booking__paid_at__extract_year + , subq_8.booking__paid_at__extract_quarter + , subq_8.booking__paid_at__extract_month + , subq_8.booking__paid_at__extract_day + , subq_8.booking__paid_at__extract_dow + , subq_8.booking__paid_at__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.listing + , subq_8.guest + , subq_8.host + , subq_8.booking__listing + , subq_8.booking__guest + , subq_8.booking__host + , subq_8.is_instant + , subq_8.booking__is_instant + , subq_8.bookings + , subq_8.instant_bookings + , subq_8.booking_value + , subq_8.max_booking_value + , subq_8.min_booking_value + , subq_8.bookers + , subq_8.average_booking_value + , subq_8.referred_bookings + , subq_8.median_booking_value + , subq_8.booking_value_p99 + , subq_8.discrete_booking_value_p99 + , subq_8.approximate_continuous_booking_value_p99 + , subq_8.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_8 + ) subq_9 + ON + subq_15.ds__day = subq_9.metric_time__day + ) subq_16 + ) subq_17 + GROUP BY + subq_17.metric_time__day + ) subq_18 + ) subq_19 + ) subq_20 + ON + subq_26.ds__day = subq_20.metric_time__day +) subq_27 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0_optimized.sql new file mode 100644 index 0000000000..26ad8ec5ea --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window__plan0_optimized.sql @@ -0,0 +1,161 @@ +test_name: test_nested_custom_offset_window +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +WITH rss_28018_cte AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 +) + +SELECT + metric_time__day AS metric_time__day + , bookings_offset_one_martian_day AS bookings_offset_one_martian_day_then_2_martian_days +FROM ( + -- Join to Time Spine Dataset + SELECT + subq_52.ds__day__lead AS metric_time__day + , subq_48.bookings_offset_one_martian_day AS bookings_offset_one_martian_day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_15 AS ( + -- Read From CTE For node_id=rss_28018 + -- Get Custom Granularity Bounds + SELECT + ds__day + , ds__martian_day + , FIRST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ) AS ds__day__row_number + FROM rss_28018_cte rss_28018_cte + ) + + SELECT + cte_15.ds__day AS ds__day + , CASE + WHEN subq_51.ds__martian_day__first_value__lead + INTERVAL (cte_15.ds__day__row_number - 1) day <= subq_51.ds__martian_day__last_value__lead + THEN subq_51.ds__martian_day__first_value__lead + INTERVAL (cte_15.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_15 cte_15 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 2) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 2) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_15 cte_15 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_50 + ) subq_51 + ON + cte_15.ds__martian_day = subq_51.ds__martian_day + ) subq_52 + INNER JOIN ( + -- Compute Metrics via Expressions + SELECT + metric_time__day + , bookings AS bookings_offset_one_martian_day + FROM ( + -- Join to Time Spine Dataset + -- Pass Only Elements: ['bookings', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_41.ds__day__lead AS metric_time__day + , SUM(subq_37.bookings) AS bookings + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_13 AS ( + -- Read From CTE For node_id=rss_28018 + -- Get Custom Granularity Bounds + SELECT + ds__day + , ds__martian_day + , FIRST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ) AS ds__day__row_number + FROM rss_28018_cte rss_28018_cte + ) + + SELECT + cte_13.ds__day AS ds__day + , CASE + WHEN subq_40.ds__martian_day__first_value__lead + INTERVAL (cte_13.ds__day__row_number - 1) day <= subq_40.ds__martian_day__last_value__lead + THEN subq_40.ds__martian_day__first_value__lead + INTERVAL (cte_13.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_13 cte_13 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_13 cte_13 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_39 + ) subq_40 + ON + cte_13.ds__martian_day = subq_40.ds__martian_day + ) subq_41 + INNER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_37 + ON + subq_41.ds__day = subq_37.metric_time__day + GROUP BY + subq_41.ds__day__lead + ) subq_47 + ) subq_48 + ON + subq_52.ds__day = subq_48.metric_time__day +) subq_55 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0.sql new file mode 100644 index 0000000000..5be53d68fa --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0.sql @@ -0,0 +1,538 @@ +test_name: test_nested_custom_offset_window_matching_grain +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +SELECT + subq_28.metric_time__day + , subq_28.metric_time__martian_day + , bookings_offset_one_martian_day AS bookings_offset_one_martian_day_then_2_martian_days +FROM ( + -- Join to Time Spine Dataset + SELECT + subq_27.metric_time__martian_day AS metric_time__martian_day + , subq_21.metric_time__day AS metric_time__day + , subq_21.bookings_offset_one_martian_day AS bookings_offset_one_martian_day + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__martian_day'] + SELECT + subq_26.ds__day + , subq_26.metric_time__martian_day + FROM ( + -- Apply Requested Granularities + SELECT + subq_25.ds__day + , subq_25.ds__day__lead AS metric_time__martian_day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_6 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_22.ds__day) OVER ( + PARTITION BY subq_22.ds__martian_day + ORDER BY subq_22.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_22.ds__day) OVER ( + PARTITION BY subq_22.ds__martian_day + ORDER BY subq_22.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_22.ds__martian_day + ORDER BY subq_22.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_22 + ) + + SELECT + cte_6.ds__day AS ds__day + , CASE + WHEN subq_24.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day <= subq_24.ds__martian_day__last_value__lead + THEN subq_24.ds__martian_day__first_value__lead + INTERVAL (cte_6.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_6 cte_6 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_23.ds__martian_day + , LEAD(subq_23.ds__martian_day__first_value, 2) OVER (ORDER BY subq_23.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_23.ds__martian_day__last_value, 2) OVER (ORDER BY subq_23.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_6.ds__martian_day + , cte_6.ds__martian_day__first_value + , cte_6.ds__martian_day__last_value + FROM cte_6 cte_6 + GROUP BY + cte_6.ds__martian_day + , cte_6.ds__martian_day__first_value + , cte_6.ds__martian_day__last_value + ) subq_23 + ) subq_24 + ON + cte_6.ds__martian_day = subq_24.ds__martian_day + ) subq_25 + ) subq_26 + ) subq_27 + INNER JOIN ( + -- Compute Metrics via Expressions + SELECT + subq_20.metric_time__martian_day + , subq_20.metric_time__day + , bookings AS bookings_offset_one_martian_day + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_19.metric_time__martian_day + , subq_19.metric_time__day + , subq_19.bookings + FROM ( + -- Aggregate Measures + SELECT + subq_18.metric_time__martian_day + , subq_18.metric_time__day + , SUM(subq_18.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'metric_time__martian_day', 'metric_time__day'] + SELECT + subq_17.metric_time__martian_day + , subq_17.metric_time__day + , subq_17.bookings + FROM ( + -- Join to Time Spine Dataset + -- Join to Custom Granularity Dataset + SELECT + subq_15.metric_time__day AS metric_time__day + , subq_9.ds__day AS ds__day + , subq_9.ds__week AS ds__week + , subq_9.ds__month AS ds__month + , subq_9.ds__quarter AS ds__quarter + , subq_9.ds__year AS ds__year + , subq_9.ds__extract_year AS ds__extract_year + , subq_9.ds__extract_quarter AS ds__extract_quarter + , subq_9.ds__extract_month AS ds__extract_month + , subq_9.ds__extract_day AS ds__extract_day + , subq_9.ds__extract_dow AS ds__extract_dow + , subq_9.ds__extract_doy AS ds__extract_doy + , subq_9.ds_partitioned__day AS ds_partitioned__day + , subq_9.ds_partitioned__week AS ds_partitioned__week + , subq_9.ds_partitioned__month AS ds_partitioned__month + , subq_9.ds_partitioned__quarter AS ds_partitioned__quarter + , subq_9.ds_partitioned__year AS ds_partitioned__year + , subq_9.ds_partitioned__extract_year AS ds_partitioned__extract_year + , subq_9.ds_partitioned__extract_quarter AS ds_partitioned__extract_quarter + , subq_9.ds_partitioned__extract_month AS ds_partitioned__extract_month + , subq_9.ds_partitioned__extract_day AS ds_partitioned__extract_day + , subq_9.ds_partitioned__extract_dow AS ds_partitioned__extract_dow + , subq_9.ds_partitioned__extract_doy AS ds_partitioned__extract_doy + , subq_9.paid_at__day AS paid_at__day + , subq_9.paid_at__week AS paid_at__week + , subq_9.paid_at__month AS paid_at__month + , subq_9.paid_at__quarter AS paid_at__quarter + , subq_9.paid_at__year AS paid_at__year + , subq_9.paid_at__extract_year AS paid_at__extract_year + , subq_9.paid_at__extract_quarter AS paid_at__extract_quarter + , subq_9.paid_at__extract_month AS paid_at__extract_month + , subq_9.paid_at__extract_day AS paid_at__extract_day + , subq_9.paid_at__extract_dow AS paid_at__extract_dow + , subq_9.paid_at__extract_doy AS paid_at__extract_doy + , subq_9.booking__ds__day AS booking__ds__day + , subq_9.booking__ds__week AS booking__ds__week + , subq_9.booking__ds__month AS booking__ds__month + , subq_9.booking__ds__quarter AS booking__ds__quarter + , subq_9.booking__ds__year AS booking__ds__year + , subq_9.booking__ds__extract_year AS booking__ds__extract_year + , subq_9.booking__ds__extract_quarter AS booking__ds__extract_quarter + , subq_9.booking__ds__extract_month AS booking__ds__extract_month + , subq_9.booking__ds__extract_day AS booking__ds__extract_day + , subq_9.booking__ds__extract_dow AS booking__ds__extract_dow + , subq_9.booking__ds__extract_doy AS booking__ds__extract_doy + , subq_9.booking__ds_partitioned__day AS booking__ds_partitioned__day + , subq_9.booking__ds_partitioned__week AS booking__ds_partitioned__week + , subq_9.booking__ds_partitioned__month AS booking__ds_partitioned__month + , subq_9.booking__ds_partitioned__quarter AS booking__ds_partitioned__quarter + , subq_9.booking__ds_partitioned__year AS booking__ds_partitioned__year + , subq_9.booking__ds_partitioned__extract_year AS booking__ds_partitioned__extract_year + , subq_9.booking__ds_partitioned__extract_quarter AS booking__ds_partitioned__extract_quarter + , subq_9.booking__ds_partitioned__extract_month AS booking__ds_partitioned__extract_month + , subq_9.booking__ds_partitioned__extract_day AS booking__ds_partitioned__extract_day + , subq_9.booking__ds_partitioned__extract_dow AS booking__ds_partitioned__extract_dow + , subq_9.booking__ds_partitioned__extract_doy AS booking__ds_partitioned__extract_doy + , subq_9.booking__paid_at__day AS booking__paid_at__day + , subq_9.booking__paid_at__week AS booking__paid_at__week + , subq_9.booking__paid_at__month AS booking__paid_at__month + , subq_9.booking__paid_at__quarter AS booking__paid_at__quarter + , subq_9.booking__paid_at__year AS booking__paid_at__year + , subq_9.booking__paid_at__extract_year AS booking__paid_at__extract_year + , subq_9.booking__paid_at__extract_quarter AS booking__paid_at__extract_quarter + , subq_9.booking__paid_at__extract_month AS booking__paid_at__extract_month + , subq_9.booking__paid_at__extract_day AS booking__paid_at__extract_day + , subq_9.booking__paid_at__extract_dow AS booking__paid_at__extract_dow + , subq_9.booking__paid_at__extract_doy AS booking__paid_at__extract_doy + , subq_9.metric_time__week AS metric_time__week + , subq_9.metric_time__month AS metric_time__month + , subq_9.metric_time__quarter AS metric_time__quarter + , subq_9.metric_time__year AS metric_time__year + , subq_9.metric_time__extract_year AS metric_time__extract_year + , subq_9.metric_time__extract_quarter AS metric_time__extract_quarter + , subq_9.metric_time__extract_month AS metric_time__extract_month + , subq_9.metric_time__extract_day AS metric_time__extract_day + , subq_9.metric_time__extract_dow AS metric_time__extract_dow + , subq_9.metric_time__extract_doy AS metric_time__extract_doy + , subq_9.listing AS listing + , subq_9.guest AS guest + , subq_9.host AS host + , subq_9.booking__listing AS booking__listing + , subq_9.booking__guest AS booking__guest + , subq_9.booking__host AS booking__host + , subq_9.is_instant AS is_instant + , subq_9.booking__is_instant AS booking__is_instant + , subq_9.bookings AS bookings + , subq_9.instant_bookings AS instant_bookings + , subq_9.booking_value AS booking_value + , subq_9.max_booking_value AS max_booking_value + , subq_9.min_booking_value AS min_booking_value + , subq_9.bookers AS bookers + , subq_9.average_booking_value AS average_booking_value + , subq_9.referred_bookings AS referred_bookings + , subq_9.median_booking_value AS median_booking_value + , subq_9.booking_value_p99 AS booking_value_p99 + , subq_9.discrete_booking_value_p99 AS discrete_booking_value_p99 + , subq_9.approximate_continuous_booking_value_p99 AS approximate_continuous_booking_value_p99 + , subq_9.approximate_discrete_booking_value_p99 AS approximate_discrete_booking_value_p99 + , subq_16.martian_day AS metric_time__martian_day + FROM ( + -- Pass Only Elements: ['ds__day', 'metric_time__day'] + SELECT + subq_14.ds__day + , subq_14.metric_time__day + FROM ( + -- Apply Requested Granularities + SELECT + subq_13.ds__day + , subq_13.ds__day__lead AS metric_time__day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_4 AS ( + -- Get Custom Granularity Bounds + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + , FIRST_VALUE(subq_10.ds__day) OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(subq_10.ds__day) OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY subq_10.ds__martian_day + ORDER BY subq_10.ds__day + ) AS ds__day__row_number + FROM ( + -- Read From Time Spine 'mf_time_spine' + SELECT + time_spine_src_28006.ds AS ds__day + , DATE_TRUNC('week', time_spine_src_28006.ds) AS ds__week + , DATE_TRUNC('month', time_spine_src_28006.ds) AS ds__month + , DATE_TRUNC('quarter', time_spine_src_28006.ds) AS ds__quarter + , DATE_TRUNC('year', time_spine_src_28006.ds) AS ds__year + , EXTRACT(year FROM time_spine_src_28006.ds) AS ds__extract_year + , EXTRACT(quarter FROM time_spine_src_28006.ds) AS ds__extract_quarter + , EXTRACT(month FROM time_spine_src_28006.ds) AS ds__extract_month + , EXTRACT(day FROM time_spine_src_28006.ds) AS ds__extract_day + , EXTRACT(isodow FROM time_spine_src_28006.ds) AS ds__extract_dow + , EXTRACT(doy FROM time_spine_src_28006.ds) AS ds__extract_doy + , time_spine_src_28006.martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 + ) subq_10 + ) + + SELECT + cte_4.ds__day AS ds__day + , CASE + WHEN subq_12.ds__martian_day__first_value__lead + INTERVAL (cte_4.ds__day__row_number - 1) day <= subq_12.ds__martian_day__last_value__lead + THEN subq_12.ds__martian_day__first_value__lead + INTERVAL (cte_4.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_4 cte_4 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + subq_11.ds__martian_day + , LEAD(subq_11.ds__martian_day__first_value, 1) OVER (ORDER BY subq_11.ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(subq_11.ds__martian_day__last_value, 1) OVER (ORDER BY subq_11.ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + cte_4.ds__martian_day + , cte_4.ds__martian_day__first_value + , cte_4.ds__martian_day__last_value + FROM cte_4 cte_4 + GROUP BY + cte_4.ds__martian_day + , cte_4.ds__martian_day__first_value + , cte_4.ds__martian_day__last_value + ) subq_11 + ) subq_12 + ON + cte_4.ds__martian_day = subq_12.ds__martian_day + ) subq_13 + ) subq_14 + ) subq_15 + INNER JOIN ( + -- Metric Time Dimension 'ds' + SELECT + subq_8.ds__day + , subq_8.ds__week + , subq_8.ds__month + , subq_8.ds__quarter + , subq_8.ds__year + , subq_8.ds__extract_year + , subq_8.ds__extract_quarter + , subq_8.ds__extract_month + , subq_8.ds__extract_day + , subq_8.ds__extract_dow + , subq_8.ds__extract_doy + , subq_8.ds_partitioned__day + , subq_8.ds_partitioned__week + , subq_8.ds_partitioned__month + , subq_8.ds_partitioned__quarter + , subq_8.ds_partitioned__year + , subq_8.ds_partitioned__extract_year + , subq_8.ds_partitioned__extract_quarter + , subq_8.ds_partitioned__extract_month + , subq_8.ds_partitioned__extract_day + , subq_8.ds_partitioned__extract_dow + , subq_8.ds_partitioned__extract_doy + , subq_8.paid_at__day + , subq_8.paid_at__week + , subq_8.paid_at__month + , subq_8.paid_at__quarter + , subq_8.paid_at__year + , subq_8.paid_at__extract_year + , subq_8.paid_at__extract_quarter + , subq_8.paid_at__extract_month + , subq_8.paid_at__extract_day + , subq_8.paid_at__extract_dow + , subq_8.paid_at__extract_doy + , subq_8.booking__ds__day + , subq_8.booking__ds__week + , subq_8.booking__ds__month + , subq_8.booking__ds__quarter + , subq_8.booking__ds__year + , subq_8.booking__ds__extract_year + , subq_8.booking__ds__extract_quarter + , subq_8.booking__ds__extract_month + , subq_8.booking__ds__extract_day + , subq_8.booking__ds__extract_dow + , subq_8.booking__ds__extract_doy + , subq_8.booking__ds_partitioned__day + , subq_8.booking__ds_partitioned__week + , subq_8.booking__ds_partitioned__month + , subq_8.booking__ds_partitioned__quarter + , subq_8.booking__ds_partitioned__year + , subq_8.booking__ds_partitioned__extract_year + , subq_8.booking__ds_partitioned__extract_quarter + , subq_8.booking__ds_partitioned__extract_month + , subq_8.booking__ds_partitioned__extract_day + , subq_8.booking__ds_partitioned__extract_dow + , subq_8.booking__ds_partitioned__extract_doy + , subq_8.booking__paid_at__day + , subq_8.booking__paid_at__week + , subq_8.booking__paid_at__month + , subq_8.booking__paid_at__quarter + , subq_8.booking__paid_at__year + , subq_8.booking__paid_at__extract_year + , subq_8.booking__paid_at__extract_quarter + , subq_8.booking__paid_at__extract_month + , subq_8.booking__paid_at__extract_day + , subq_8.booking__paid_at__extract_dow + , subq_8.booking__paid_at__extract_doy + , subq_8.ds__day AS metric_time__day + , subq_8.ds__week AS metric_time__week + , subq_8.ds__month AS metric_time__month + , subq_8.ds__quarter AS metric_time__quarter + , subq_8.ds__year AS metric_time__year + , subq_8.ds__extract_year AS metric_time__extract_year + , subq_8.ds__extract_quarter AS metric_time__extract_quarter + , subq_8.ds__extract_month AS metric_time__extract_month + , subq_8.ds__extract_day AS metric_time__extract_day + , subq_8.ds__extract_dow AS metric_time__extract_dow + , subq_8.ds__extract_doy AS metric_time__extract_doy + , subq_8.listing + , subq_8.guest + , subq_8.host + , subq_8.booking__listing + , subq_8.booking__guest + , subq_8.booking__host + , subq_8.is_instant + , subq_8.booking__is_instant + , subq_8.bookings + , subq_8.instant_bookings + , subq_8.booking_value + , subq_8.max_booking_value + , subq_8.min_booking_value + , subq_8.bookers + , subq_8.average_booking_value + , subq_8.referred_bookings + , subq_8.median_booking_value + , subq_8.booking_value_p99 + , subq_8.discrete_booking_value_p99 + , subq_8.approximate_continuous_booking_value_p99 + , subq_8.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_8 + ) subq_9 + ON + subq_15.ds__day = subq_9.metric_time__day + LEFT OUTER JOIN + ***************************.mf_time_spine subq_16 + ON + subq_15.metric_time__day = subq_16.ds + ) subq_17 + ) subq_18 + GROUP BY + subq_18.metric_time__martian_day + , subq_18.metric_time__day + ) subq_19 + ) subq_20 + ) subq_21 + ON + subq_27.metric_time__martian_day = subq_21.metric_time__martian_day +) subq_28 diff --git a/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0_optimized.sql b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0_optimized.sql new file mode 100644 index 0000000000..00c6ce8139 --- /dev/null +++ b/tests_metricflow/snapshots/test_custom_granularity.py/SqlPlan/DuckDB/test_nested_custom_offset_window_matching_grain__plan0_optimized.sql @@ -0,0 +1,169 @@ +test_name: test_nested_custom_offset_window_matching_grain +test_filename: test_custom_granularity.py +sql_engine: DuckDB +--- +-- Compute Metrics via Expressions +WITH rss_28018_cte AS ( + -- Read From Time Spine 'mf_time_spine' + SELECT + ds AS ds__day + , martian_day AS ds__martian_day + FROM ***************************.mf_time_spine time_spine_src_28006 +) + +SELECT + metric_time__day AS metric_time__day + , metric_time__martian_day AS metric_time__martian_day + , bookings_offset_one_martian_day AS bookings_offset_one_martian_day_then_2_martian_days +FROM ( + -- Join to Time Spine Dataset + SELECT + subq_54.ds__day__lead AS metric_time__martian_day + , subq_50.metric_time__day AS metric_time__day + , subq_50.bookings_offset_one_martian_day AS bookings_offset_one_martian_day + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_15 AS ( + -- Read From CTE For node_id=rss_28018 + -- Get Custom Granularity Bounds + SELECT + ds__martian_day + , FIRST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ) AS ds__day__row_number + FROM rss_28018_cte rss_28018_cte + ) + + SELECT + CASE + WHEN subq_53.ds__martian_day__first_value__lead + INTERVAL (cte_15.ds__day__row_number - 1) day <= subq_53.ds__martian_day__last_value__lead + THEN subq_53.ds__martian_day__first_value__lead + INTERVAL (cte_15.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_15 cte_15 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 2) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 2) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_15 cte_15 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_52 + ) subq_53 + ON + cte_15.ds__martian_day = subq_53.ds__martian_day + ) subq_54 + INNER JOIN ( + -- Compute Metrics via Expressions + SELECT + metric_time__martian_day + , metric_time__day + , bookings AS bookings_offset_one_martian_day + FROM ( + -- Join to Time Spine Dataset + -- Join to Custom Granularity Dataset + -- Pass Only Elements: ['bookings', 'metric_time__martian_day', 'metric_time__day'] + -- Aggregate Measures + -- Compute Metrics via Expressions + SELECT + subq_45.martian_day AS metric_time__martian_day + , subq_42.ds__day__lead AS metric_time__day + , SUM(subq_38.bookings) AS bookings + FROM ( + -- Offset Base Granularity By Custom Granularity Period(s) + WITH cte_13 AS ( + -- Read From CTE For node_id=rss_28018 + -- Get Custom Granularity Bounds + SELECT + ds__day + , ds__martian_day + , FIRST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__first_value + , LAST_VALUE(ds__day) OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) AS ds__martian_day__last_value + , ROW_NUMBER() OVER ( + PARTITION BY ds__martian_day + ORDER BY ds__day + ) AS ds__day__row_number + FROM rss_28018_cte rss_28018_cte + ) + + SELECT + cte_13.ds__day AS ds__day + , CASE + WHEN subq_41.ds__martian_day__first_value__lead + INTERVAL (cte_13.ds__day__row_number - 1) day <= subq_41.ds__martian_day__last_value__lead + THEN subq_41.ds__martian_day__first_value__lead + INTERVAL (cte_13.ds__day__row_number - 1) day + ELSE NULL + END AS ds__day__lead + FROM cte_13 cte_13 + INNER JOIN ( + -- Offset Custom Granularity Bounds + SELECT + ds__martian_day + , LEAD(ds__martian_day__first_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__first_value__lead + , LEAD(ds__martian_day__last_value, 1) OVER (ORDER BY ds__martian_day) AS ds__martian_day__last_value__lead + FROM ( + -- Get Unique Rows for Custom Granularity Bounds + SELECT + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + FROM cte_13 cte_13 + GROUP BY + ds__martian_day + , ds__martian_day__first_value + , ds__martian_day__last_value + ) subq_40 + ) subq_41 + ON + cte_13.ds__martian_day = subq_41.ds__martian_day + ) subq_42 + INNER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + SELECT + DATE_TRUNC('day', ds) AS metric_time__day + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_38 + ON + subq_42.ds__day = subq_38.metric_time__day + LEFT OUTER JOIN + ***************************.mf_time_spine subq_45 + ON + subq_42.ds__day__lead = subq_45.ds + GROUP BY + subq_45.martian_day + , subq_42.ds__day__lead + ) subq_49 + ) subq_50 + ON + subq_54.ds__day__lead = subq_50.metric_time__martian_day +) subq_57 diff --git a/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_base_grain__query_output.txt b/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_base_grain__query_output.txt index f5cfd0c52d..ae298cb30f 100644 --- a/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_base_grain__query_output.txt +++ b/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_base_grain__query_output.txt @@ -3,19 +3,26 @@ test_filename: test_offset_metrics.py docstring: Gives a side by side comparison of bookings and bookings_offset_one_martian_day. --- -metric_time__martian_day metric_time__day bookings bookings_offset_one_martian_day --------------------------- ------------------- ---------- --------------------------------- -2020-01-08T00:00:00 2019-12-01T00:00:00 1 None -2020-01-08T00:00:00 2019-12-18T00:00:00 10 None -2020-01-08T00:00:00 2019-12-19T00:00:00 18 None -2020-01-08T00:00:00 2019-12-20T00:00:00 2 None -2020-01-08T00:00:00 2020-01-01T00:00:00 5 None -2020-01-08T00:00:00 2020-01-02T00:00:00 9 None -2020-01-08T00:00:00 2020-01-03T00:00:00 1 None -2020-01-09T00:00:00 2022-08-27T00:00:00 None 1 -2020-01-09T00:00:00 2022-09-13T00:00:00 None 10 -2020-01-09T00:00:00 2022-09-14T00:00:00 None 18 -2020-01-09T00:00:00 2022-09-15T00:00:00 None 2 -2020-01-09T00:00:00 2022-09-27T00:00:00 None 5 -2020-01-09T00:00:00 2022-09-28T00:00:00 None 9 -2020-01-09T00:00:00 2022-09-29T00:00:00 None 1 +metric_time__martian_day metric_time__day bookings bookings_offset_one_martian_day bookings_martian_day_over_martian_day bookings_offset_one_martian_day_then_2_martian_days +-------------------------- ------------------- ---------- --------------------------------- --------------------------------------- ----------------------------------------------------- +2020-01-08T00:00:00 2019-12-01T00:00:00 1 None None None +2020-01-08T00:00:00 2019-12-18T00:00:00 10 None None None +2020-01-08T00:00:00 2019-12-19T00:00:00 18 None None None +2020-01-08T00:00:00 2019-12-20T00:00:00 2 None None None +2020-01-08T00:00:00 2020-01-01T00:00:00 5 None None None +2020-01-08T00:00:00 2020-01-02T00:00:00 9 None None None +2020-01-08T00:00:00 2020-01-03T00:00:00 1 None None None +2020-01-09T00:00:00 2022-08-27T00:00:00 None 1 None None +2020-01-09T00:00:00 2022-09-13T00:00:00 None 10 None None +2020-01-09T00:00:00 2022-09-14T00:00:00 None 18 None None +2020-01-09T00:00:00 2022-09-15T00:00:00 None 2 None None +2020-01-09T00:00:00 2022-09-27T00:00:00 None 5 None None +2020-01-09T00:00:00 2022-09-28T00:00:00 None 9 None None +2020-01-09T00:00:00 2022-09-29T00:00:00 None 1 None None +2028-02-17T00:00:00 2028-02-17T00:00:00 None None None 1 +2028-03-05T00:00:00 2028-03-05T00:00:00 None None None 10 +2028-03-06T00:00:00 2028-03-06T00:00:00 None None None 18 +2028-03-07T00:00:00 2028-03-07T00:00:00 None None None 2 +2028-03-19T00:00:00 2028-03-19T00:00:00 None None None 5 +2028-03-20T00:00:00 2028-03-20T00:00:00 None None None 9 +2028-03-21T00:00:00 2028-03-21T00:00:00 None None None 1 diff --git a/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_matching_custom_grain__query_output.txt b/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_matching_custom_grain__query_output.txt index c1af7abb87..66c0005bc2 100644 --- a/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_matching_custom_grain__query_output.txt +++ b/tests_metricflow/snapshots/test_offset_metrics.py/str/DuckDB/test_custom_offset_window_with_matching_custom_grain__query_output.txt @@ -3,7 +3,7 @@ test_filename: test_offset_metrics.py docstring: Gives a side by side comparison of bookings and bookings_offset_one_martian_day. --- -metric_time__martian_day booking__ds__martian_day bookings bookings_offset_one_martian_day --------------------------- -------------------------- ---------- --------------------------------- -2020-01-08T00:00:00 2020-01-08T00:00:00 46 None -2020-01-09T00:00:00 2020-01-09T00:00:00 None 46 +metric_time__martian_day booking__ds__martian_day bookings bookings_offset_one_martian_day bookings_martian_day_over_martian_day +-------------------------- -------------------------- ---------- --------------------------------- --------------------------------------- +2020-01-08T00:00:00 2020-01-08T00:00:00 46 None None +2020-01-09T00:00:00 2020-01-09T00:00:00 None 46 None