sql-server - 如何检索多个详细记录加上主记录作为单行?

标签 sql-server pivot crosstab

我有两个结构与此类似的表:

人:

ID   Name   Age
 1   Jack    25
 2   Jill    23

测试:

ID  PersonID  TestID  Result
 1         1       1     125
 2         1       2     120
 3         1       3      75
 4         2       1      90
 5         2       2      95
 6         2       3     7.2

是否有一种方法可以使用单个语句检索该数据,使主表中的每条记录都显示在一行中?像这样的事情:

PersonID  Name  Age  Test1  Test2  Test3
       1  Jack   25    125    120     75
       2  Jill   23     90     95    7.2

到目前为止,我想出的唯一方法是创建一个迭代详细记录并填充临时表的函数。不太优雅。

提前致谢

最佳答案

为了获得此结果,您需要使用PIVOT功能。这会将数据从多行转换为列。

如果您提前知道这些值,或者您的 TestId 值数量有限,那么您可以对查询进行硬编码,使查询静态化。

SELECT Name,
  Age,
  [1] AS Test1,
  [2] AS Test2,
  [3] AS Test3 
FROM
( 
  SELECT P.Name, P.Age, t.TestID, t.Result 
  FROM tests t
  INNER JOIN person P 
  ON p.ID = t.PersonID
) T 
PIVOT
(
  sum(Result) 
  FOR TestID IN ([1], [2], [3])
) piv;

参见SQL Fiddle with Demo .

但是,如果您有未知数量的 TestId 值,那么您将需要使用动态 SQL 在运行时生成列列表。您的代码将是:

DECLARE @cols AS NVARCHAR(MAX),
    @colNames AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(testId) 
                    from tests
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colNames = STUFF((SELECT distinct ',' + QUOTENAME(testId) +' as Test'+cast(testId as varchar(10))
                    from tests
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Name, age, ' + @colnames + ' from 
             (
                select P.Name, P.Age, t.TestID, t.Result 
                from tests t
                inner join person P 
                  on p.ID = t.PersonID
            ) x
            pivot 
            (
                sum(Result)
                for TestID in (' + @cols + ')
            ) p '

execute(@query)

参见SQL Fiddle with Demo .

它们都会生成相同的结果,区别在于,如果测试 ID 的数量发生变化,动态结果会增加/减少列:

| NAME | AGE | TEST1 | TEST2 | TEST3 |
--------------------------------------
| Jack |  25 |   125 |   120 |    75 |
| Jill |  23 |    90 |    95 |   7.2 |

关于sql-server - 如何检索多个详细记录加上主记录作为单行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14786414/

相关文章:

SQL查询特定时间段内最大可用商品数(预订系统)

sql-server - SSIS:动态连接字符串集成安全模式的配置

MySQL 将行转换为动态列数

sql - PostgreSQL 如何将行转换为列

python - 如何对 pandas crosstab 中的行求和并制作一个新的 crosstab?

sql-server - SQL Server 驱动程序和 SQL Server 网络接口(interface)之间的关系

json - T-SQL OPENJSON WITH 子句

java - 如何将不同列的值分组到一行中?

mysql - 如何将列标题标记为格式化日期?

sql-server - 如何在动态数据透视表中将两列组合成单列