选择列名作为值的SQL

选择列名作为值的SQL,sql,views,Sql,Views,我有一个列名称的数据表: period, Truck, Car, Boat 其中,列包含数值,句点列是具有1到48的标识列,因此有48行 我想将这个表转换成一种格式,其中我有一个名称列、一个值列以及句点列,例如 period, NameOfVehicle, Value 我想创建原始表的视图来执行此操作?如何选择列名并将其和该列中的正确值放入“车辆名称”和“值”列中?如果您有固定列,则始终可以执行以下操作: SELECT period, 'Truck' AS NameOfVehicle, Tr

我有一个列名称的数据表:

period, Truck, Car, Boat
其中,列包含数值,句点列是具有1到48的标识列,因此有48行

我想将这个表转换成一种格式,其中我有一个名称列、一个值列以及句点列,例如

period, NameOfVehicle, Value

我想创建原始表的视图来执行此操作?如何选择列名并将其和该列中的正确值放入“车辆名称”和“值”列中?

如果您有固定列,则始终可以执行以下操作:

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语句将有点困难,并且将依赖供应商特定的功能。

虽然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]为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;
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;