Postgres table 选择多列并将结果(列)动态转换为行 - 将列转置为行
Postgres table selecting multiple columns and dynamically converting the result (column) into row - transposing column to rows
我有以下类型的table(伤害)结构
Rowid damageTypeACount damageTypeBCount damageTypeCCount
1 23 44 33
而且我还需要读取这些 table 行,结果为(标题、id 是手动设置的),将列转换为行但具有附加属性
id damagecountsum label
1 23 Damage Type A
2 44 Damage Type B
3 33 Damage Type C
我做了以下查询并且它有效但想知道是否有更好的方法
SELECT 1 as id,
damageTypeACount as damagecount,
"Damage Type A Count" as label
FROM Damage where rowId=1
UNION ALL
SELECT 2 as id,
damageTypeBCount as damagecount,
"Damage Type B Count" as label
FROM Damage where rowId=1
UNION ALL
SELECT 3 as id,
damageTypeCCount as damagecount,
"Damage Type C Count" as label
FROM Damage where rowId=1
上面的查询按预期工作,但我想知道是否可以在单个 select 语句中将列转换为行
您可以使用横向联接取消透视:
select x.*
from damage d
cross join lateral (values
(d.rowId, d.damageTypeACount, 'Damage Type A'),
(d.rowId, d.damageTypeBCount, 'Damage Type B'),
(d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(id, damagecount, label)
这会重新影响每个生成的行的原始 id
。您还可以使用 row_number()
:
生成新的 ID
select row_number() over(order by id, label) id, x.*
from damage d
cross join lateral (values
(d.rowId, d.damageTypeACount, 'Damage Type A'),
(d.rowId, d.damageTypeBCount, 'Damage Type B'),
(d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(rowId, damagecount, label)
如果需要,您可以使用 where
子句过滤结果集:
where d.rowId = 1
我有以下类型的table(伤害)结构
Rowid damageTypeACount damageTypeBCount damageTypeCCount
1 23 44 33
而且我还需要读取这些 table 行,结果为(标题、id 是手动设置的),将列转换为行但具有附加属性
id damagecountsum label
1 23 Damage Type A
2 44 Damage Type B
3 33 Damage Type C
我做了以下查询并且它有效但想知道是否有更好的方法
SELECT 1 as id,
damageTypeACount as damagecount,
"Damage Type A Count" as label
FROM Damage where rowId=1
UNION ALL
SELECT 2 as id,
damageTypeBCount as damagecount,
"Damage Type B Count" as label
FROM Damage where rowId=1
UNION ALL
SELECT 3 as id,
damageTypeCCount as damagecount,
"Damage Type C Count" as label
FROM Damage where rowId=1
上面的查询按预期工作,但我想知道是否可以在单个 select 语句中将列转换为行
您可以使用横向联接取消透视:
select x.*
from damage d
cross join lateral (values
(d.rowId, d.damageTypeACount, 'Damage Type A'),
(d.rowId, d.damageTypeBCount, 'Damage Type B'),
(d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(id, damagecount, label)
这会重新影响每个生成的行的原始 id
。您还可以使用 row_number()
:
select row_number() over(order by id, label) id, x.*
from damage d
cross join lateral (values
(d.rowId, d.damageTypeACount, 'Damage Type A'),
(d.rowId, d.damageTypeBCount, 'Damage Type B'),
(d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(rowId, damagecount, label)
如果需要,您可以使用 where
子句过滤结果集:
where d.rowId = 1