如何在SQL中透视表

时间:2013-06-04 13:37:03

标签: asp.net sql sql-server

Lab Test Name    Source Collected Date    Results
Urea             6/4/2013 12:00:00 AM           5
Uric Acid        6/4/2013 12:00:00 AM          10
Cholesterol      6/3/2013 12:00:00 AM          25

我有一个具有上述值的数据表 我需要将其转移到以下结构:

                      Urea  Uric Acid   Cholesterol
6/4/2013 12:00:00 AM     5         10             -
6/3/2013 12:00:00 AM     -          -            25

2 个答案:

答案 0 :(得分:3)

如果您查看Mikael链接的答案,您将意识到您需要动态构建pivot语句的列,因为PIVOT语法不允许在FOR子句中进行子选择。所以基本上你需要做这样的事情:

DECLARE
@cols AS NVARCHAR(MAX),
@y    AS INT,
@sql  AS NVARCHAR(MAX);

-- Construct the column list for the IN clause
-- e.g., [Urea],[Uric Acid],[Cholesterol]
SET @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT (LabTestName) AS y FROM YourTable) AS Y
ORDER BY y
FOR XML PATH('')),
1, 1, N'');

您现在可以这样构建PIVOT语句:

set @SQL = N'

SELECT   SourceCollectedDate,'+@cols+N' 
FROM    YourTable
PIVOT (
SUM(results) FOR LabTestName IN ( '+@cols+N')
) AS PivotTable
ORDER BY SourceCollectedDate desc
'

执行它:

EXEC sp_executesql @sql

将产生:

SourceCollectedDate     Urea    Uric Acid   Cholesterol
2013-06-04 00:00:00.000 5       10          NULL
2013-06-03 00:00:00.000 NULL    NULL        25

请注意,我的示例中有YourTable作为表名。您需要将其替换为您的实际表名。

SQL Fiddle(基于乍得创造的)

答案 1 :(得分:1)

这是一个不需要pivot或动态SQL的解决方案。权衡是您需要在查询中指定每个可能的实验室测试名称。

SELECT [Source Collected Date],
  MAX(CASE WHEN [Lab Test Name] = 'Urea'
      THEN Results ELSE NULL END) AS Urea,
  MAX(CASE WHEN [Lab Test Name] = 'Uric Acid'
      THEN Results ELSE NULL END) AS [Uric Acid],
  MAX(CASE WHEN [Lab Test Name] = 'Cholesterol'
      THEN Results ELSE NULL END) AS Cholesterol
FROM Table1
GROUP BY [Source Collected Date]

看到它正常工作here