英文:
Snowflake: How to include NULL value in the UNPIVOT
问题
要包括NULL值在UNPIVOT中,您可以使用Snowflake中的NVL函数来实现。以下是修改后的查询:
select Month, Name, NVL(value, NULL) as Value from
TableName
unpivot
(
Value
for Name in (Col_1,Col_2,Col_3,Col_4,Col_5)
) u
这将在结果中包括NULL值,如您所期望的那样:
Month Name Value
-----------------------
Jan Col_1 NULL
Jan Col_2 NULL
Jan Col_3 1
Jan Col_4 1
Jan Col_5 1
英文:
Requirement: Include NULL values in the UNPIVOT
I have a table below:
Month Col_1 Col_2 Col_3 Col_4 Col_5
---------------------------------------------
Jan NULL NULL 1 1 1
I want to unpivot this table
My query:
select Month, Name, value from
TableName
unpivot
(
Value
for Name in (Col_1,Col_2,Col_3,Col_4,Col_5)
) u
Result:
This results without the NULL values below:
Month Name Value
-----------------------
Jan Col_3 1
Jan Col_4 1
Jan Col_5 1
Expected Result:
I want the NULLs to be included in the result
Month Name Value
-----------------------
Jan Col_1 NULL
Jan Col_2 NULL
Jan Col_3 1
Jan Col_4 1
Jan Col_5 1
Any help would be appreciated in Snowflake
答案1
得分: 1
作为一种解决方法,如果您不希望在您的任何列中出现负数1。
with cte as (select
month
,ifnull(col_1,-1) col_1
,ifnull(col_2,-1) col_2
,ifnull(col_3,-1) col_3
,ifnull(col_4,-1) col_4
,ifnull(col_5,-1) col_5
from UNPIVOT_TEST
)
select
month
,name
,case when value=-1 then NULL else value end as value
from cte unpivot
(
value for name in ( col_1,col_2,col_3,col_4,col_5)
);
英文:
as a workaround if you are not expecting negative 1 in any of your columns.
with cte as (select
month
,ifnull(col_1,-1) col_1
,ifnull(col_2,-1) col_2
,ifnull(col_3,-1) col_3
,ifnull(col_4,-1) col_4
,ifnull(col_5,-1) col_5
from UNPIVOT_TEST
)
select
month
,name
,case when value=-1 then NULL else value end as value
from cte unpivot
(
value for name in ( col_1,col_2,col_3,col_4,col_5)
);
答案2
得分: 1
不要有别的内容。以下是翻译好的部分:
"Instead of using unpivot, you can use lateral flatten for this, by creating an object containing the key/values for your column names and values. This solution also dynamically assembles the column names you want to unpivot on, which may be helpful if you have a lot of columns to manage, or the source table might change over time."
"不要使用unpivot,您可以使用lateral flatten来实现此目标,方法是创建一个包含列名和值的键/值对对象。这种解决方案还会动态组装您要解构的列名,这在您需要管理大量列或源表可能会随时间变化时可能会有帮助。"
"First of all create the test data from your example:"
"首先,根据您的示例创建测试数据:"
"create or replace view test_data as
select *
from (VALUES ('Jan', NULL, NULL, 1, 1, 1) ) as
raw_data (Month, Col_1, Col_2, Col_3, Col_4, Col_5);"
"创建或替换测试数据视图test_data,如下所示:"
"从(VALUES('Jan',NULL,NULL,1,1,1))中选择*作为raw_data(Month,Col_1,Col_2,Col_3,Col_4,Col_5);"
"Then :"
"接下来:"
"with
kc_r1 as (
-- Return a 1 row result containing only the columns that you want to unpivot on.
-- 2 examples below."
"使用kc_r1作为:"
"-- 返回只包含您想要解构的列的1行结果。"
"-- 下面是2个示例。"
"select * EXCLUDE month from test_data limit 1"
"从test_data中选择* EXCLUDE month,限制为1行"
"-- select * ILIKE 'COL_%' from test_data limit 1 "
"kca as ("
"选择kca作为:"
" select
-- Create an array containing the column names required in the 'unpivot'
object_keys(object_construct_keep_null(*)) k_array
from kc_r1"
"从kc_r1中选择:"
"-- 创建一个包含在“unpivot”中需要的列名的数组"
"object_keys(object_construct_keep_null(*)) k_array"
"o as ("
"选择o作为:"
" select
month,
object_pick(object_construct_keep_null(test_data.*), kca.k_array) k_v
from kca, test_data)"
"从kca和test_data中选择:"
"month,"
"object_pick(object_construct_keep_null(test_data.*), kca.k_array) k_v"
"Select
month 'Month',
key 'Name',
value 'Value'
from kca, o, lateral flatten (input => k_v);"
"选择:"
"month 'Month',"
"key 'Name',"
"value 'Value'"
"from kca, o, lateral flatten (input => k_v);"
"Not sure if the column names in your example reflect your actual data but some of the column names your using are reserved words, which is not good practice."
"不确定您的示例中的列名是否反映了您的实际数据,但您使用的一些列名是保留字,这不是一个好的做法。"
英文:
Instead of using unpivot, you can use lateral flatten for this, by creating an object containing the key/values for your column names and values. This solution also dynamically assembles the column names you want to unpivot on, which may be helpful if you have a lot of columns to manage, or the source table might change over time.
First of all create the test data from your example:
create or replace view test_data as
select *
from (VALUES ('Jan', NULL, NULL, 1, 1, 1) ) as
raw_data (Month, Col_1, Col_2, Col_3, Col_4, Col_5);
Then :
with
kc_r1 as (
-- Return a 1 row result containing only the columns that you want to unpivot on.
-- 2 examples below.
select * EXCLUDE month from test_data limit 1
-- select * ILIKE 'COL_%' from test_data limit 1
),
kca as (
select
-- Create an array containing the column names required in the 'unpivot'
object_keys(object_construct_keep_null(*)) k_array
from kc_r1
),
o as (
select
month,
object_pick(object_construct_keep_null(test_data.*), kca.k_array) k_v
from kca, test_data)
Select
month "Month",
key "Name",
value "Value"
from kca, o, lateral flatten (input => k_v)
;
Not sure if the column names in your example reflect your actual data but some of the column names your using are reserved words, which is not good practice.
答案3
得分: 0
我相信这将在Snowflake中起作用(尽管我假设concat()
是一个有效的函数)
with numbers as (
select 1 as n union all
select 2 as n union all
select 3 as n union all
select 4 as n union all
select 5 as n
)
select
t.Month
, concat('col_', numbers.n) as name
, case
when numbers.n = 1 then col_1
when numbers.n = 2 then col_2
when numbers.n = 3 then col_3
when numbers.n = 4 then col_4
when numbers.n = 5 then col_5
end as value
from tablename t
cross join numbers
跨连接到5行执行所需的行扩展,然后我们可以使用case
表达式将所有值放入一个列中。如果无法使用连接方法,您还可以为名称使用case
表达式。
英文:
I believe this will work in snowflake (although I'm assuming concat() is a valid function)
with numbers as (
select 1 as n union all
select 2 as n union all
select 3 as n union all
select 4 as n union all
select 5 as n
)
select
t.Month
, concat('col_', numbers.n) as name
, case
when numbers.n = 1 then col_1
when numbers.n = 2 then col_2
when numbers.n = 3 then col_3
when numbers.n = 4 then col_4
when numbers.n = 5 then col_5
end as value
from tablename t
cross join numbers
The cross join to 5 rows does the needed row expansion, then we can use a case expression to put all values into 1 column. You could also use a case expression for name if you can't use the concatenation approach.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论