在数据透视查询中组合字段
Combining fields in a pivot query
我有一个 table 的 key-value 结构,其中包含以下字段:
Title
PageNo
LineNo
Key
Value
Units
我有以下非常有效的数据透视查询:
SELECT * FROM
(SELECT Title, [Key],IIF(NOT [Units] IS NULL,[Value] + ' ' +[Units],
[Value]) AS ValueUnits FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
ORDER BY Title
我得到的结果是:
Title Field_1 Field_2 Field_3
-------------------------------------
我需要如何更改我的数据透视查询才能获得如下内容:
Title Field_1 (Units) Field_2(Units) Field_3(Units)
----------------------------------------------------------
and/or 像这样:
Title Field_1 Units Field_2 Units Field_3 Units
在我的结果集中?
我试过了:
SELECT * FROM
(SELECT Title, [Key] + '(' + [Units] + ')' As KeyAndUnits,[Value]
FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([Value])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
但这给了我一个错误"Invalid column name [Key]"
我也试过:
SELECT * FROM
(SELECT Title, [Key], [Key] + '(' + [Units] + ')' As KeyAndUnits,[Value]
FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([Value])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
但这弄乱了我的结果集
谁能给我指出正确的方向?
编辑:
示例数据:
________________________________
标题关键值单位
------------------------------------
标题 1 Field_1 4000 磅
标题 1 Field_2 150 页
标题 1 Field_3 200 毫升
标题 2 Field_2 300 页
标题 3 Field_1 350 磅
标题 3 Field_3 55 毫升
示例输出:
Title Field_1 Units Field_2 Units Field3 Units
-------------------------------------------------------------
Title1 4000 lbs 150 pages 200 ml
Title2 300 pages
Title3 350 lbs 55 ml
和
Title Field_1 (lbs) Field_2 (pages) Field3 (ml)
-------------------------------------------------------------
Title1 4000 150 200
Title2 300
Title3 350 55
如果同一列的单位不总是相同,则第二个可能不起作用
您可以尝试对字段名称使用别名
SELECT
Title,
[Field_1] AS [Field_1 (Units)],
[Field_2] AS [Field_2 (Units)],
[Field_3] AS [Field_3 (Units)]
FROM
(SELECT Title,
[Key],
IIF(NOT [FieldUnits] IS NULL,
[Value] + ' ' +[Units],
[FieldValue]) AS ValueUnits
FROM Table1
WHERE [Key] LIKE 'Field_%'
) AS Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN ([Field_1],[Field_2],[Field_3]) ) As Piv
ORDER BY
Title
您的第二个查询具有串联值。只需添加一个键列即可修复错误。
SELECT
Title,
[Field_1] AS [Field_1 (Units)],
[Field_2] AS [Field_2 (Units)],
[Field_3] AS [Field_3 (Units)]
FROM
(SELECT Title,
[Key],
ISNULL([Key],'') + ISNULL(' (' + [Value] + ')','') AS KeyValue
FROM Table1
WHERE [Key] LIKE 'Field_%'
) AS Data
PIVOT(
MAX([KeyValue])
FOR [Key] IN ([Field_1],[Field_2],[Field_3]) ) As Piv
ORDER BY
Title
这里有一些信息可以让您开始使用动态数据透视表。
DECLARE @FieldNames VARCHAR(MAX)
SELECT @FieldNames = COALESCE(@FieldName + ',','') + '[' + Key + ' (' + Units + ')]'
FROM Table1
DECLARE @Sql VARCHAR(MAX) = CONCAT(
' SELECT Title, ' + @FieldName
,' FROM (your subquery.. needs to have Key + ' (' + Units + ')' As Key ) AS sq'
,' PIVOT ('
,' MAX(KeyValue)'
,' FOR Key in (' + @FieldNames + ')'
,' AS p')
EXEC(@Sql)
我实际上找到了一个相当简单的解决方案 - 我将值和单位与“/”连接起来,然后使用 CHARINDEX 在 select 列表中的“/”上拆分。
SELECT Title,
SUBSTRING([Field_1],0,CHARINDEX('/',[Field_1])) AS [Field_1],
SUBSTRING([Field_1],CHARINDEX('/',[Field_1])+1,LEN([Field_1]-1) AS[Field_1Units],
SUBSTRING([Field_2],0,CHARINDEX('/',[Field_2])) AS [Field_2],
SUBSTRING([Field_2],CHARINDEX('/',[Field_2])+1,LEN([Field_2]-1) AS [Field_2Units],
SUBSTRING([Field_3],0,CHARINDEX('/',[Field_3])) AS [Field_3],
SUBSTRING([Field_3],CHARINDEX('/',[Field_3])+1,LEN([Field_3]-1) AS [Field_3Units]
FROM
(SELECT Title, [Key],IIF([Units]<>'',[Value] + '/' +[Units],
[Value]) AS ValueUnits FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
ORDER BY Title
当您需要旋转多列时,您可能会发现 PIVOT
之前的分组和条件聚合旋转方法更简单、更易于维护。自己判断:
SELECT
Title,
Field_1 = MAX(CASE [Key] WHEN 'Field_1' THEN Value END),
Field_1Units = MAX(CASE [Key] WHEN 'Field_1' THEN Units END),
Field_2 = MAX(CASE [Key] WHEN 'Field_2' THEN Value END),
Field_2Units = MAX(CASE [Key] WHEN 'Field_2' THEN Units END),
Field_3 = MAX(CASE [Key] WHEN 'Field_3' THEN Value END),
Field_3Units = MAX(CASE [Key] WHEN 'Field_3' THEN Units END)
FROM
dbo.Table1
GROUP BY
Title
WHERE
[Key] LIKE 'Field_%'
;
我有一个 table 的 key-value 结构,其中包含以下字段:
Title
PageNo
LineNo
Key
Value
Units
我有以下非常有效的数据透视查询:
SELECT * FROM
(SELECT Title, [Key],IIF(NOT [Units] IS NULL,[Value] + ' ' +[Units],
[Value]) AS ValueUnits FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
ORDER BY Title
我得到的结果是:
Title Field_1 Field_2 Field_3
-------------------------------------
我需要如何更改我的数据透视查询才能获得如下内容:
Title Field_1 (Units) Field_2(Units) Field_3(Units)
----------------------------------------------------------
and/or 像这样:
Title Field_1 Units Field_2 Units Field_3 Units
在我的结果集中?
我试过了:
SELECT * FROM
(SELECT Title, [Key] + '(' + [Units] + ')' As KeyAndUnits,[Value]
FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([Value])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
但这给了我一个错误"Invalid column name [Key]"
我也试过:
SELECT * FROM
(SELECT Title, [Key], [Key] + '(' + [Units] + ')' As KeyAndUnits,[Value]
FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([Value])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
但这弄乱了我的结果集
谁能给我指出正确的方向?
编辑:
示例数据: ________________________________ 标题关键值单位 ------------------------------------ 标题 1 Field_1 4000 磅 标题 1 Field_2 150 页 标题 1 Field_3 200 毫升 标题 2 Field_2 300 页 标题 3 Field_1 350 磅 标题 3 Field_3 55 毫升
示例输出:
Title Field_1 Units Field_2 Units Field3 Units
-------------------------------------------------------------
Title1 4000 lbs 150 pages 200 ml
Title2 300 pages
Title3 350 lbs 55 ml
和
Title Field_1 (lbs) Field_2 (pages) Field3 (ml)
-------------------------------------------------------------
Title1 4000 150 200
Title2 300
Title3 350 55
如果同一列的单位不总是相同,则第二个可能不起作用
您可以尝试对字段名称使用别名
SELECT
Title,
[Field_1] AS [Field_1 (Units)],
[Field_2] AS [Field_2 (Units)],
[Field_3] AS [Field_3 (Units)]
FROM
(SELECT Title,
[Key],
IIF(NOT [FieldUnits] IS NULL,
[Value] + ' ' +[Units],
[FieldValue]) AS ValueUnits
FROM Table1
WHERE [Key] LIKE 'Field_%'
) AS Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN ([Field_1],[Field_2],[Field_3]) ) As Piv
ORDER BY
Title
您的第二个查询具有串联值。只需添加一个键列即可修复错误。
SELECT
Title,
[Field_1] AS [Field_1 (Units)],
[Field_2] AS [Field_2 (Units)],
[Field_3] AS [Field_3 (Units)]
FROM
(SELECT Title,
[Key],
ISNULL([Key],'') + ISNULL(' (' + [Value] + ')','') AS KeyValue
FROM Table1
WHERE [Key] LIKE 'Field_%'
) AS Data
PIVOT(
MAX([KeyValue])
FOR [Key] IN ([Field_1],[Field_2],[Field_3]) ) As Piv
ORDER BY
Title
这里有一些信息可以让您开始使用动态数据透视表。
DECLARE @FieldNames VARCHAR(MAX)
SELECT @FieldNames = COALESCE(@FieldName + ',','') + '[' + Key + ' (' + Units + ')]'
FROM Table1
DECLARE @Sql VARCHAR(MAX) = CONCAT(
' SELECT Title, ' + @FieldName
,' FROM (your subquery.. needs to have Key + ' (' + Units + ')' As Key ) AS sq'
,' PIVOT ('
,' MAX(KeyValue)'
,' FOR Key in (' + @FieldNames + ')'
,' AS p')
EXEC(@Sql)
我实际上找到了一个相当简单的解决方案 - 我将值和单位与“/”连接起来,然后使用 CHARINDEX 在 select 列表中的“/”上拆分。
SELECT Title,
SUBSTRING([Field_1],0,CHARINDEX('/',[Field_1])) AS [Field_1],
SUBSTRING([Field_1],CHARINDEX('/',[Field_1])+1,LEN([Field_1]-1) AS[Field_1Units],
SUBSTRING([Field_2],0,CHARINDEX('/',[Field_2])) AS [Field_2],
SUBSTRING([Field_2],CHARINDEX('/',[Field_2])+1,LEN([Field_2]-1) AS [Field_2Units],
SUBSTRING([Field_3],0,CHARINDEX('/',[Field_3])) AS [Field_3],
SUBSTRING([Field_3],CHARINDEX('/',[Field_3])+1,LEN([Field_3]-1) AS [Field_3Units]
FROM
(SELECT Title, [Key],IIF([Units]<>'',[Value] + '/' +[Units],
[Value]) AS ValueUnits FROM Table1 WHERE [Key] LIKE 'Field_%') as Data
PIVOT(
MAX([ValueUnits])
FOR [Key] IN([Field_1],[Field_2],[Field_3])) As Piv
ORDER BY Title
当您需要旋转多列时,您可能会发现 PIVOT
之前的分组和条件聚合旋转方法更简单、更易于维护。自己判断:
SELECT
Title,
Field_1 = MAX(CASE [Key] WHEN 'Field_1' THEN Value END),
Field_1Units = MAX(CASE [Key] WHEN 'Field_1' THEN Units END),
Field_2 = MAX(CASE [Key] WHEN 'Field_2' THEN Value END),
Field_2Units = MAX(CASE [Key] WHEN 'Field_2' THEN Units END),
Field_3 = MAX(CASE [Key] WHEN 'Field_3' THEN Value END),
Field_3Units = MAX(CASE [Key] WHEN 'Field_3' THEN Units END)
FROM
dbo.Table1
GROUP BY
Title
WHERE
[Key] LIKE 'Field_%'
;