From d1c872bf0df18115a7bd2bba88a5c9bd6bf872c5 Mon Sep 17 00:00:00 2001 From: Dennis-UiPath Date: Wed, 20 Dec 2023 15:58:01 +0100 Subject: [PATCH] feat: add stddev macro --- README.md | 7 ++++++ dbt_project.yml | 2 +- integration_tests/models/schema.yml | 9 +++++++ integration_tests/models/test_stddev.sql | 30 ++++++++++++++++++++++++ macros/multiple_databases/stddev.sql | 9 +++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 integration_tests/models/test_stddev.sql create mode 100644 macros/multiple_databases/stddev.sql diff --git a/README.md b/README.md index df8dc57..b30664c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ This dbt package contains macros for SQL functions to run the dbt project on mul - [date_add](#date_add-source) - [date_from_timestamp](#date_from_timestamp-source) - [datediff](#datediff-source) + - [stddev](#stddev-source) - [string_agg](#string_agg-source) - [timestamp_from_date](#timestamp_from_date-source) - [timestamp_from_parts](#timestamp_from_parts-source) @@ -111,6 +112,12 @@ This macro generates an id field that can be used as a column for the current mo Usage: `{{ pm_utils.id() }}` +#### stddev ([source](macros/multiple_databases/stddev.sql)) +This macro computes the standard deviation of a set of values, `null` values are ignored in the calculation. This macro can only be used as an aggregate function. For SQL Server, at least one of the values provided should not be `null`. + +Usage: +`{{ pm_utils.stddev('[expression]') }}` + #### string_agg ([source](macros/multiple_databases/string_agg.sql)) This macro aggregates string fields separated by the given delimiter. If no delimiter is specified, strings are separated by a comma followed by a space. This macro can only be used as an aggregate function. For SQL Server, the maximum supported length is 2000. diff --git a/dbt_project.yml b/dbt_project.yml index 05a0d57..5ddb164 100644 --- a/dbt_project.yml +++ b/dbt_project.yml @@ -1,5 +1,5 @@ name: 'pm_utils' -version: '1.1.2' +version: '1.2.0' config-version: 2 require-dbt-version: [">=1.0.0", "<2.0.0"] diff --git a/integration_tests/models/schema.yml b/integration_tests/models/schema.yml index b7f714a..ca3817d 100644 --- a/integration_tests/models/schema.yml +++ b/integration_tests/models/schema.yml @@ -90,3 +90,12 @@ models: - equal_value: actual: '`add_to_null_value`' expected: '`add_to_null_value_expected`' + + - name: test_stddev + tests: + - equal_value: + actual: '`stddev_actual`' + expected: '`stddev_expected`' + - equal_value: + actual: '`stddev_with_null_values_actual`' + expected: '`stddev_with_null_values_expected`' diff --git a/integration_tests/models/test_stddev.sql b/integration_tests/models/test_stddev.sql new file mode 100644 index 0000000..0916db1 --- /dev/null +++ b/integration_tests/models/test_stddev.sql @@ -0,0 +1,30 @@ +with Input_data as ( + select val + from (values (1),(2),(3),(4)) as Input(val) +), + +Input_data_with_null as ( + select val + from (values (1),(2),(null),(4)) as Input(val) +), + +stddev_input_data as ( + select + round({{ pm_utils.stddev('val') }}, 3) as `stddev_input_data` + from Input_data +), + +stddev_input_data_null as ( + select + round({{ pm_utils.stddev('val') }}, 3) as `stddev_input_data_null` + from Input_data_with_null +) + +select + {{ pm_utils.to_varchar('stddev_input_data.`stddev_input_data`') }} as `stddev_actual`, + '1.291' as `stddev_expected`, + + {{ pm_utils.to_varchar('stddev_input_data_null.`stddev_input_data_null`') }} as `stddev_with_null_values_actual`, + '1.528' as `stddev_with_null_values_expected` +from stddev_input_data +cross join stddev_input_data_null diff --git a/macros/multiple_databases/stddev.sql b/macros/multiple_databases/stddev.sql new file mode 100644 index 0000000..e8c050b --- /dev/null +++ b/macros/multiple_databases/stddev.sql @@ -0,0 +1,9 @@ +{% macro stddev(field, relation) %} + +{%- if target.type in ('databricks', 'snowflake') -%} + stddev({{ field }}) +{%- elif target.type == 'sqlserver' -%} + stdev({{ field }}) +{%- endif -%} + +{% endmacro %}