在数据透视查询中组合字段

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_%'
;