Skip to content

Commit e4f5c73

Browse files
Fix Redshift PARTITION BY error by excluding constant bucket_seasonality expression
Co-Authored-By: Yosef Arbiv <[email protected]>
1 parent 9ddf019 commit e4f5c73

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

macros/edr/data_monitoring/anomaly_detection/get_anomaly_scores_query.sql

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,29 @@
1717

1818
{%- if test_configuration.seasonality == 'day_of_week' %}
1919
{%- set bucket_seasonality_expr = elementary.edr_day_of_week_expression('bucket_end') %}
20+
{%- set has_seasonality = true %}
2021

2122
{%- elif test_configuration.seasonality == 'hour_of_day' %}
2223
{%- set bucket_seasonality_expr = elementary.edr_hour_of_day_expression('bucket_end') %}
24+
{%- set has_seasonality = true %}
2325

2426
{%- elif test_configuration.seasonality == 'hour_of_week' %}
2527
{%- set bucket_seasonality_expr = elementary.edr_hour_of_week_expression('bucket_end') %}
28+
{%- set has_seasonality = true %}
2629

2730
{%- else %}
2831
{%- set bucket_seasonality_expr = elementary.const_as_text('no_seasonality') %}
32+
{%- set has_seasonality = false %}
2933
{%- endif %}
34+
35+
{# Build PARTITION BY clause for window functions.
36+
Redshift doesn't support constant expressions in PARTITION BY, so we exclude
37+
bucket_seasonality when it's a constant (i.e., when has_seasonality is false). #}
38+
{%- set partition_by_keys = "metric_name, full_table_name, column_name, dimension, dimension_value" %}
39+
{%- if has_seasonality %}
40+
{%- set partition_by_keys = partition_by_keys ~ ", bucket_seasonality" %}
41+
{%- endif %}
42+
3043
{%- set detection_end = elementary.get_detection_end(test_configuration.detection_delay) %}
3144
{%- set detection_end_expr = elementary.edr_cast_as_timestamp(elementary.edr_datetime_to_sql(detection_end)) %}
3245
{%- set min_bucket_start_expr = elementary.get_trunc_min_bucket_start_expr(detection_end, metric_properties, test_configuration.days_back) %}
@@ -182,11 +195,11 @@
182195
bucket_duration_hours,
183196
updated_at,
184197
should_exclude_from_training,
185-
avg(case when not should_exclude_from_training then metric_value end) over (partition by metric_name, full_table_name, column_name, dimension, dimension_value, bucket_seasonality order by bucket_end asc rows between unbounded preceding and current row) as training_avg,
186-
{{ elementary.standard_deviation('case when not should_exclude_from_training then metric_value end') }} over (partition by metric_name, full_table_name, column_name, dimension, dimension_value, bucket_seasonality order by bucket_end asc rows between unbounded preceding and current row) as training_stddev,
187-
count(case when not should_exclude_from_training then metric_value end) over (partition by metric_name, full_table_name, column_name, dimension, dimension_value, bucket_seasonality order by bucket_end asc rows between unbounded preceding and current row) as training_set_size,
188-
last_value(case when not should_exclude_from_training then bucket_end end) over (partition by metric_name, full_table_name, column_name, dimension, dimension_value, bucket_seasonality order by bucket_end asc rows between unbounded preceding and current row) training_end,
189-
first_value(case when not should_exclude_from_training then bucket_end end) over (partition by metric_name, full_table_name, column_name, dimension, dimension_value, bucket_seasonality order by bucket_end asc rows between unbounded preceding and current row) as training_start
198+
avg(case when not should_exclude_from_training then metric_value end) over (partition by {{ partition_by_keys }} order by bucket_end asc rows between unbounded preceding and current row) as training_avg,
199+
{{ elementary.standard_deviation('case when not should_exclude_from_training then metric_value end') }} over (partition by {{ partition_by_keys }} order by bucket_end asc rows between unbounded preceding and current row) as training_stddev,
200+
count(case when not should_exclude_from_training then metric_value end) over (partition by {{ partition_by_keys }} order by bucket_end asc rows between unbounded preceding and current row) as training_set_size,
201+
last_value(case when not should_exclude_from_training then bucket_end end) over (partition by {{ partition_by_keys }} order by bucket_end asc rows between unbounded preceding and current row) training_end,
202+
first_value(case when not should_exclude_from_training then bucket_end end) over (partition by {{ partition_by_keys }} order by bucket_end asc rows between unbounded preceding and current row) as training_start
190203
from grouped_metrics
191204
where not is_excluded
192205
{{ dbt_utils.group_by(14) }}

0 commit comments

Comments
 (0)