将 header 行转换为列 PostgreSQL
Converting the header row to a column PostgreSQL
我是 PostgreSQL 新手。我有一个 table 包含下面提到的三列,我想将 header 行转换为在另一列中具有相应值的列,最后是一个新列,用于检查该值是否丢失.
ID NAME EMAIL SALARY
1 John '' 1000
2 Sam feeeee@asd.com 6000
3 Tom aeesde@asd.com 9000
4 Bob mnnke@asd.com 500
5 Lari kllewl@asd.com 3000
每个 ID 的预期输出:
ID fields Value Verified
1 NAME John Yes
EMAIL '' No
SALARY 1000 Yes
2 NAME Sam Yes
EMAIL feeeee@asd.com Yes
SALARY 6000 Yes
您所谓的 header 行根本就不是行,而只是列名。每个 ID 和列需要一行。虽然这是我宁愿在应用程序中而不是在 SQL 中执行的操作,但它当然是可能的。每列需要一个查询。将他们的结果与 UNION ALL
.
粘合在一起
select
id,
'NAME' as fields,
name as value,
case when name is null or name = '' then 'No' else 'Yes' as verified
from mytable
union all
select
id,
'EMAIL' as fields,
email as value,
case when email is null or email = '' then 'No' else 'Yes' as verified
from mytable
union all
select
id,
'SALARY' as fields,
cast(salary as varchar) as value,
case when salary is null then 'No' else 'Yes' as verified
from mytable
order by id, fields;
但如前所述,最好只 select * from mytable
并关心应用中数据的呈现方式。这可能也快得多。
另一种选择是使用带有 VALUES 子句的 CROSS JOIN,将列转换为行:
select t.id,
u.*,
case
when u.value = '' or u.value is null then 'No'
else 'Yes'
end as verified
from the_table t
cross join lateral (
values ('NAME', name), ('EMAIL', email), ('SALARY', salary::text)
) as u(column_name, value)
order by t.id, u.column_name
这写起来更短,也更容易维护,但我发现 Thorsten Kettner 的 UNION ALL 方法在某些情况下更快。
我是 PostgreSQL 新手。我有一个 table 包含下面提到的三列,我想将 header 行转换为在另一列中具有相应值的列,最后是一个新列,用于检查该值是否丢失.
ID NAME EMAIL SALARY
1 John '' 1000
2 Sam feeeee@asd.com 6000
3 Tom aeesde@asd.com 9000
4 Bob mnnke@asd.com 500
5 Lari kllewl@asd.com 3000
每个 ID 的预期输出:
ID fields Value Verified
1 NAME John Yes
EMAIL '' No
SALARY 1000 Yes
2 NAME Sam Yes
EMAIL feeeee@asd.com Yes
SALARY 6000 Yes
您所谓的 header 行根本就不是行,而只是列名。每个 ID 和列需要一行。虽然这是我宁愿在应用程序中而不是在 SQL 中执行的操作,但它当然是可能的。每列需要一个查询。将他们的结果与 UNION ALL
.
select
id,
'NAME' as fields,
name as value,
case when name is null or name = '' then 'No' else 'Yes' as verified
from mytable
union all
select
id,
'EMAIL' as fields,
email as value,
case when email is null or email = '' then 'No' else 'Yes' as verified
from mytable
union all
select
id,
'SALARY' as fields,
cast(salary as varchar) as value,
case when salary is null then 'No' else 'Yes' as verified
from mytable
order by id, fields;
但如前所述,最好只 select * from mytable
并关心应用中数据的呈现方式。这可能也快得多。
另一种选择是使用带有 VALUES 子句的 CROSS JOIN,将列转换为行:
select t.id,
u.*,
case
when u.value = '' or u.value is null then 'No'
else 'Yes'
end as verified
from the_table t
cross join lateral (
values ('NAME', name), ('EMAIL', email), ('SALARY', salary::text)
) as u(column_name, value)
order by t.id, u.column_name
这写起来更短,也更容易维护,但我发现 Thorsten Kettner 的 UNION ALL 方法在某些情况下更快。