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
如果您想在 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);
结果
我目前在 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
如果您想在 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);
结果