SQL 服务器:在视图中使用列值作为 table headers

SQL Server : using column values as table headers in a view

我目前在 SQL 服务器中有一个 table,看起来像这样:

Machine Serial Date Parameter Value
Machine 1 12345 7/22/2021 Param 1 789
Machine 1 12345 7/22/2021 Param 2 456
Machine 1 67890 7/22/2021 Param 1 123
Machine 1 67890 7/22/2021 Param 2 456
Machine 1 34567 7/22/2021 Param 1 789
Machine 1 34567 7/22/2021 Param 3 123

我正在尝试创建一个视图,将这个 table 转换成这样的东西,其中每一行都由它的序列号定义,视图 headers 由'Parameter'列

Serial Machine Date Param 1 Param 2 Param 3
12345 Machine 1 7/22/2021 789 456
67890 Machine 1 7/22/2021 123 456
34567 Machine 1 7/22/2021 789 123

这里的意图是原始 table 可以包含任意数量的唯一参数,然后生成的视图将按序列号分组,并根据分配给它的参数用它各自的值填充每一列。

到目前为止,我尝试过使用动态 SQL,但未能产生任何结果。我过去做过类似的事情,但参数列中没有动态数量的参数。这样的事情在数据库端是否可能,或者这种操作是否需要在客户端发生?

一种方法是在视图定义中的附加列上使用 CASE 语句,如下所示:

SELECT Serial,
       Machine,
       Date,
       CASE WHEN Parameter = 'Param1' THEN Value ELSE '' END AS Param1,
       CASE WHEN Parameter = 'Param2' THEN Value ELSE '' END AS Param2,
       CASE WHEN Parameter = 'Param3' THEN Value ELSE '' END AS Param3

这不会很好地扩展到大量参数,但它应该可以很好地满足您在此处描述的内容。

如果您需要它是动态的或容纳更多值,您应该考虑使用 PIVOT

编辑:为了完整性,也添加了该方法。

DROP TABLE IF EXISTS #pivot;

CREATE TABLE #pivot
 (Serial INT,
  Machine VARCHAR(20),
  [Date] DATETIME,
  Parameter VARCHAR(6),
  VALUE INT)

INSERT INTO #pivot
VALUES (12345, 'Machine 1', GETDATE(), 'Param1', 789),
       (12345, 'Machine 1', GETDATE(), 'Param2', 456),
       (67890, 'Machine 1', GETDATE(), 'Param1', 789),
       (67890, 'Machine 1', GETDATE(), 'Param2', 456),
       (34567, 'Machine 1', GETDATE(), 'Param1', 789),
       (34567, 'Machine 1', GETDATE(), 'Param3', 123);

SELECT *
  FROM #pivot;


SELECT Serial, Machine, Date, Param1, Param2, Param3
  FROM #pivot AS p
 PIVOT (
    SUM(p.Value)
    FOR p.Parameter
    IN (Param1, Param2, Param3)
 ) pvt

https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15

如果您想在 SQL 服务器而不是表示层中执行此操作,则需要动态 SQL

例子

Declare @SQL varchar(max) = '
Select *
From (
        Select Serial
              ,Machine
              ,Date
              ,Parameter
              ,Value
        From #YourTable
     ) src
 Pivot (sum(Value) For [Parameter] in (' + stuff((Select Distinct ',' + QuoteName(Parameter) From  #YourTable Order By 1 For XML Path('') ),1,1,'')  + ') ) pvt'
Exec(@SQL);

结果