我有一个包含列名的数据表:
period, Truck, Car, Boat
如果列包含数值,而period列是1到48的标识列,那么有48行。
我想将这个表格按到一个格式,我有一个名称列和一个值列以及句号列,例如。
period, NameOfVehicle, Value
我想创建一个orignal表的视图来做到这一点?如何选择列名并将它们以及该列中的正确值放入NameOfVehicle和Value列?
答案 0 :(得分:10)
如果您有固定的列,您可以随时执行此操作:
SELECT period, 'Truck' AS NameOfVehicle, Truck AS Value FROM vehicle
UNION ALL
SELECT period, 'Car', Car FROM vehicle
UNION ALL
SELECT period, 'Boat', Boat FROM vehicle
如果列是动态的或未知的,那么它会更难,并且将依赖特定于供应商的功能来查询模式和动态SQL语句。
答案 1 :(得分:3)
虽然cletus的查询是正确的,但值得指出的是,您可以在SQL Server 2005及更高版本中使用关键字UNPIVOT来执行几乎相同的操作:
select
period, nameOfVehicle, value
from T unpivot (
value for nameOfVehicle in ([Car],[Truck],[Boat])
) as U;
UNPIVOT和cletus的解决方案之间的区别在于UNPIVOT不包含[value] IS NULL的行。如果你需要NULL,你必须有些偷偷摸摸并使用一个永远不会出现在表中的值(这里我使用一个空字符串):
with X(period,Car,Truck,Boat) as (
select period,coalesce(Car,''),coalesce(Truck,''),coalesce(Boat,'')
from T
)
select
period, nameOfVehicle, case when value = '' then null else value end as value
from X unpivot (
value for nameOfVehicle in ([Car],[Truck],[Boat])
) as U;
根据您在unpivoting后保留的列,这可能是另一个选项(此解决方案将保留NULL值):
select
period,
nameOfVehicle,
max(case nameOfVehicle
when 'Truck' then Truck
when 'Car' then Car
when 'Boat' then Boat end) as value
from T cross join (
values ('Truck'),('Car'),('Boat')
) as Columns(nameOfVehicle)
group by period, nameOfVehicle;