我有一个返回单行数据的查询。让我们说它看起来像这样(带有列标题)。
Fruit | Veg | Meats | Nuts |
----------------------------------------
Apple Lettuce Veal Almond
而不是这个,我想将这一行作为两列表返回,列/字段名称在最左边的列中。像这样:
FieldName | Value |
-----------------------
Fruit Apple
Veg Lettuce
Meats Veal
Nuts Almond
似乎应该有一些非痛苦的方法来实现这一点,但如果有,我似乎无法找到它。打砖墙。这甚至可能吗?
非常感谢任何意见。
编辑:查询返回的结果不是静态的,因此我无法明确定义列标题。
编辑2:我正在尝试将其中一些建议付诸实践,但仍然无法通过多个列来实现此功能。这是我的代码:
SELECT
TOP 10
FieldName,
CAST(FieldValue as varchar(MAX)) As FieldValue
FROM Meter M
UNPIVOT([FieldValue] FOR FieldName IN ([MeterName],[MID])) UP
WHERE ClientNumber = 12300
每次都会收到错误“Msg 8167,Level 16,State 1,Line 4 列“MID”的类型与UNPIVOT列表中指定的其他列的类型冲突。“
我看了这个,它似乎是一个与列类型/长度相关的问题,无论我如何投射FieldValue,都是同样的错误。有什么想法吗?
编辑3:列冲突的解决方案......
从原始表中转换结果将不起作用,因此我必须使用派生表并在那里进行转换,以便返回到PIVOT的列都是相同的数据类型。奇怪,但我能找到的唯一解决办法就是。
SELECT
FieldName,
CAST(FieldValue as varchar(MAX)) As FieldValue,
FROM
(
/*
Derived table so that we can control the column
types for everything selected, because PIVOT demands
that every pivoted column be of the same data type and
length.
*/
SELECT
TOP 1
CAST(M.MeterName as varchar(MAX)) As MeterName,
CAST(M.MID as varchar(MAX)) As MID,
CAST(D.DeviceType as varchar(MAX)) As DeviceType
FROM Meter M
INNER JOIN CurrentDevice D ON
D.ClientNumber = M.ClientNumber AND
D.MID = M.MID
WHERE
M.ClientNumber = 12300
) T
UNPIVOT([FieldValue] FOR FieldName IN ([MeterName],[MID],[DeviceType])) UP
答案 0 :(得分:8)
对于SQL Server 2005+,您可以使用UNPIVOT
:
SELECT FieldName, Value
FROM YourTable T
UNPIVOT([Value] FOR FieldName IN (Fruit, Veg, Meats, Nuts)) UP
针对新要求进行了更新
好的,如果您不知道表的列,则需要动态SQL。首先,转到this link。然后你可以尝试下面的内容:
DECLARE @Fields NVARCHAR(MAX), @Sql NVARCHAR(MAX)
SELECT @Fields = STUFF((SELECT DISTINCT ',' + QUOTENAME(Name)
FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID('YourTable')
FOR XML PATH('')),1,1,'')
SET @Sql = '
SELECT FieldName, Value
FROM YourTable T
UNPIVOT([Value] FOR FieldName IN ('+@Fields+')) UP
'
EXEC sp_executesql @sql
答案 1 :(得分:4)
您可以使用动态UNPIVOT查询
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ','+ QUOTENAME( name) from sys.columns
where object_id= object_id('your_table')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select FieldName, Value
FROM your_table T
UNPIVOT([Value] FOR FieldName IN ('+@cols+')) P'
exec(@query)
答案 2 :(得分:0)