将行转移到没有聚合的列

jli*_*ted 19 sql pivot

试图找出如何编写动态数据透视sql语句.哪里TEST_NAME可以有多达12个不同的值(因此有12列).一些VAL将是Int,Decimal或Varchar数据类型.我见过的大多数例子都包括一些聚合.我期待一个直接价值的支点.

Source Table 

????????????????????????????
? TEST_NAME ? SBNO ?  VAL  ?
????????????????????????????
? Test1     ?    1 ? 0.304 ?
? Test1     ?    2 ? 0.31  ?
? Test1     ?    3 ? 0.306 ?
? Test2     ?    1 ? 2.3   ?
? Test2     ?    2 ? 2.5   ?
? Test2     ?    3 ? 2.4   ?
? Test3     ?    1 ? PASS  ?
? Test3     ?    2 ? PASS  ?
????????????????????????????


Desired Output 
????????????????????????????
? SBNO Test1 Test2   Test3 ?
????????????????????????????
? 1    0.304  2.3    PASS  ?
? 2    0.31   2.5    PASS  ?
? 3    0.306  2.4    NULL  ?
????????????????????????????
Run Code Online (Sandbox Code Playgroud)

Tar*_*ryn 29

PIVOT函数需要聚合才能使其工作.您的VAL列似乎是,varchar因此您必须使用MAXMIN聚合函数.

如果测试次数有限,那么您可以对值进行硬编码:

select sbno, Test1, Test2, Test3
from
(
  select test_name, sbno, val
  from yourtable
) d
pivot
(
  max(val)
  for test_name in (Test1, Test2, Test3)
) piv;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

在您的OP中,您声明您将有更多行转换为列.如果是这种情况,那么您可以使用动态SQL:

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

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

set @query = 'SELECT sbno,' + @cols + '
             from 
             (
                select test_name, sbno, val
                from yourtable
            ) x
            pivot 
            (
                max(val)
                for test_name in (' + @cols + ')
            ) p '

execute(@query)
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

两个版本都会给出相同的结果:

| SBNO | TEST1 | TEST2 |  TEST3 |
---------------------------------
|    1 | 0.304 |   2.3 |   PASS |
|    2 |  0.31 |   2.5 |   PASS |
|    3 | 0.306 |   2.4 | (null) |
Run Code Online (Sandbox Code Playgroud)


Sam*_*ina 5

如果不进行汇总,就无法实现PIVOT。

CREATE TABLE #table1
(
    TEST_NAME VARCHAR(10),
    SBNO VARCHAR(10),
    VAL VARCHAR(10)
);

INSERT INTO #table1 (TEST_NAME, SBNO, VAL)
VALUES ('Test1' ,'1', '0.304'),
       ('Test1' ,'2', '0.31'),
       ('Test1' ,'3', '0.306'),
       ('Test2' ,'1', '2.3'),
       ('Test2' ,'2', '2.5'),
       ('Test2' ,'3', '2.4'),
       ('Test3' ,'1', 'PASS'),
       ('Test3' ,'2', 'PASS')

WITH T AS
(
    SELECT SBNO, VAL, TEST_NAME    
      FROM #table1
) 
SELECT *
  FROM T
 PIVOT (MAX(VAL) FOR TEST_NAME IN([Test1], [Test2], [Test3])) P
Run Code Online (Sandbox Code Playgroud)