forked from dbt-labs/dbt-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unpivot.sql
64 lines (47 loc) · 2.4 KB
/
unpivot.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
{#
Pivot values from columns to rows. Similar to pandas DataFrame melt() function.
Example Usage: {{ unpivot(relation=ref('users'), cast_to='integer', exclude=['id','created_at']) }}
Arguments:
relation: Relation object, required.
cast_to: The datatype to cast all unpivoted columns to. Default is varchar.
exclude: A list of columns to keep but exclude from the unpivot operation. Default is none.
remove: A list of columns to remove from the resulting table. Default is none.
field_name: Destination table column name for the source table column names.
value_name: Destination table column name for the pivoted values
#}
{% macro unpivot(relation=none, cast_to='varchar', exclude=none, remove=none, field_name='field_name', value_name='value', table=none) -%}
{% if table %}
{% do exceptions.warn("Warning: the `unpivot` macro no longer accepts a `table` parameter. This parameter will be deprecated in a future release of dbt-utils. Use the `relation` parameter instead") %}
{% endif %}
{% if relation and table %}
{{ exceptions.raise_compiler_error("Error: both the `relation` and `table` parameters were provided to `unpivot` macro. Choose one only (we recommend `relation`).") }}
{% elif not relation and table %}
{% set relation=table %}
{% elif not relation and not table %}
{{ exceptions.raise_compiler_error("Error: argument `relation` is required for `unpivot` macro.") }}
{% endif %}
{%- set exclude = exclude if exclude is not none else [] %}
{%- set remove = remove if remove is not none else [] %}
{%- set include_cols = [] %}
{%- set table_columns = {} %}
{%- do table_columns.update({relation: []}) %}
{%- do dbt_utils._is_relation(relation, 'unpivot') -%}
{%- set cols = adapter.get_columns_in_relation(relation) %}
{%- for col in cols -%}
{%- if col.column.lower() not in remove|map('lower') and col.column.lower() not in exclude|map('lower') -%}
{% do include_cols.append(col) %}
{%- endif %}
{%- endfor %}
{%- for col in include_cols -%}
select
{%- for exclude_col in exclude %}
{{ exclude_col }},
{%- endfor %}
cast('{{ col.column }}' as {{ dbt_utils.type_string() }}) as {{ field_name }},
cast({{ col.column }} as {{ cast_to }}) as {{ value_name }}
from {{ relation }}
{% if not loop.last -%}
union all
{% endif -%}
{%- endfor -%}
{%- endmacro %}