Skip to content

Commit ba99ffb

Browse files
authored
Safe subtract (#748)
* Add macro definition * Add seed file for tests * Add integration test * Update readme * Update exception message * Correct docs for safe_add and safe_subtract
1 parent eaa0e41 commit ba99ffb

File tree

5 files changed

+63
-1
lines changed

5 files changed

+63
-1
lines changed

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Check [dbt Hub](https://hub.getdbt.com/dbt-labs/dbt_utils/latest/) for the lates
4949
- [generate_surrogate_key](#generate_surrogate_key-source)
5050
- [safe_add](#safe_add-source)
5151
- [safe_divide](#safe_divide-source)
52+
- [safe_subtract](#safe_subtract-source)
5253
- [pivot](#pivot-source)
5354
- [unpivot](#unpivot-source)
5455
- [width_bucket](#width_bucket-source)
@@ -1055,7 +1056,7 @@ This macro implements a cross-database way to sum nullable fields using the fiel
10551056
**Usage:**
10561057
10571058
```
1058-
{{ dbt_utils.safe_add('field_a', 'field_b'[,...]) }}
1059+
{{ dbt_utils.safe_add(['field_a', 'field_b', ...]) }}
10591060
```
10601061

10611062
#### safe_divide ([source](macros/cross_db_utils/safe_divide.sql))
@@ -1073,6 +1074,16 @@ This macro performs division but returns null if the denominator is 0.
10731074
{{ dbt_utils.safe_divide('numerator', 'denominator') }}
10741075
```
10751076

1077+
#### safe_subtract ([source](macros/sql/safe_subtract.sql))
1078+
1079+
This macro implements a cross-database way to take the difference of nullable fields using the fields specified.
1080+
1081+
**Usage:**
1082+
1083+
```
1084+
{{ dbt_utils.safe_subtract(['field_a', 'field_b', ...]) }}
1085+
```
1086+
10761087
#### pivot ([source](macros/sql/pivot.sql))
10771088

10781089
This macro pivots values from rows to columns.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
field_1,field_2,field_3,expected
2+
3,2,1,0
3+
4,,3,1
4+
,,2,-2
5+
,,,0

integration_tests/models/sql/schema.yml

+6
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ models:
120120
- assert_equal:
121121
actual: actual
122122
expected: expected
123+
124+
- name: test_safe_subtract
125+
tests:
126+
- assert_equal:
127+
actual: actual
128+
expected: expected
123129

124130
- name: test_safe_divide
125131
tests:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
with data as (
3+
4+
select * from {{ ref('data_safe_subtract') }}
5+
6+
)
7+
8+
select
9+
{{ dbt_utils.safe_subtract(['field_1', 'field_2', 'field_3']) }} as actual,
10+
expected
11+
12+
from data

macros/sql/safe_subtract.sql

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{%- macro safe_subtract(field_list) -%}
2+
{{ return(adapter.dispatch('safe_subtract', 'dbt_utils')(field_list)) }}
3+
{% endmacro %}
4+
5+
{%- macro default__safe_subtract(field_list) -%}
6+
7+
{%- if field_list is not iterable or field_list is string or field_list is mapping -%}
8+
9+
{%- set error_message = '
10+
Warning: the `safe_subtract` macro takes a single list argument instead of \
11+
string arguments. The {}.{} model triggered this warning. \
12+
'.format(model.package_name, model.name) -%}
13+
14+
{%- do exceptions.raise_compiler_error(error_message) -%}
15+
16+
{%- endif -%}
17+
18+
{% set fields = [] %}
19+
20+
{%- for field in field_list -%}
21+
22+
{% do fields.append("coalesce(" ~ field ~ ", 0)") %}
23+
24+
{%- endfor -%}
25+
26+
{{ fields|join(' -\n ') }}
27+
28+
{%- endmacro -%}

0 commit comments

Comments
 (0)