使用Dyamic Pivot查询?

时间:2016-04-28 08:19:50

标签: sql sql-server pivot pivot-table

我有下表。 (此表中没有主键)

ID   |    IC      |    Name   |     UGCOS   |  MCOS     
---------------------------------------------------------
1AA  |  A123456B  |  Edmund   |  Australia  |  Denmark    
1AA  |  A123456B  |  Edmund   |  Australia  |  France     
2CS  |  C435664C  |  Grace    |  Norway     |  NULL       
3TG  |  G885595H  |  Rae      |  NULL       |  Japan    

我需要得到这样的结果。

ID   |    IC      |    Name   |     UGCOS   |  MCOS     |  MCOS1   
--------------------------------------------------------------------
1AA  |  A123456B  |  Edmund   |  Australia  |  Denmark  |  France
2CS  |  C435664C  |  Grace    |  Norway     |  NULL     |  NULL
3TG  |  G885595H  |  Rae      |  NULL       |  Japan    |  NULL

谷歌搜索过,似乎PIVOT是我需要做的。但是我不确定如何实现我的表格。如果有人可以帮助我,那将是很大的帮助。谢谢!

4 个答案:

答案 0 :(得分:2)

这是一个带有连锁结果的建议:

@RunWith(MyClassRunner.class)
@Params("paramFor1stRun", "paramFor2ndRun")
class MyTest {
  @Test
  public void doTest() {..}
}

结果

CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))  
INSERT INTO #tmpTbl VALUES
 ('1AA','A123456B','Edmund','Australia','Denmark')    
,('1AA','A123456B','Edmund','Australia','France')   
,('2CS','C435664C','Grace','Norway',NULL)     
,('3TG','G885595H','Rae',NULL,'Japan');

SELECT ID,IC,Name,UGCOS,
       (
        STUFF(
          (
            SELECT ' ,' + x.MCOS
            FROM #tmpTbl AS x
            WHERE x.ID=outerTbl.ID
            FOR XML PATH('')
          ),1,2,''
        )
       ) AS MCOS
FROM #tmpTbl AS outerTbl
GROUP BY ID,IC,Name,UGCOS;
GO
DROP TABLE #tmpTbl;

答案 1 :(得分:2)

我会创建第二个答案,因为这种方法与我的第一个完全不同:

此动态查询将首先找到不同ID的最大数量,然后构建动态数据透视

CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))  
INSERT INTO #tmpTbl VALUES
 ('1AA','A123456B','Edmund','Australia','Denmark')    
,('1AA','A123456B','Edmund','Australia','France')   
,('1AA','A123456B','Edmund','Australia','OneMore')   
,('2CS','C435664C','Grace','Norway',NULL)     
,('3TG','G885595H','Rae',NULL,'Japan');
GO

DECLARE @maxCount INT=(SELECT TOP 1 COUNT(*) FROM #tmpTbl GROUP BY ID ORDER BY COUNT(ID) DESC);
DECLARE @colNames VARCHAR(MAX)=
(
    STUFF
    (
        (
        SELECT TOP(@maxCount)
               ',MCOS' + CAST(ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS VARCHAR(10))
        FROM sys.objects --take any large table or - better! - an numbers table or a tally CTE
        FOR XML PATH('')
        ),1,1,''
    )
);

DECLARE @cmd VARCHAR(MAX)=
'SELECT p.*
FROM
(
    SELECT *
          ,''MCOS'' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT NULL)) AS VARCHAR(10)) AS colName 
    FROM #tmpTbl
) AS tbl
PIVOT
(
    MIN(MCOS) FOR colName IN(' + @colNames + ')
) AS p';

EXEC(@cmd);
GO

DROP TABLE #tmpTbl;

结果

1AA A123456B    Edmund  Australia   Denmark France  OneMore
2CS C435664C    Grace   Norway      NULL    NULL    NULL
3TG G885595H    Rae     NULL        Japan   NULL    NULL

答案 2 :(得分:1)

使用Cross Apply和Pivot我们可以实现这个目标

 DECLARE @Table1 TABLE 
        ( ID  varchar(3),  IC  varchar(8),  Name  varchar(6),  UGCOS  varchar(9),  MCOS  varchar(7))
    ;

    INSERT INTO @Table1
        ( ID ,  IC ,  Name ,  UGCOS ,  MCOS )
    VALUES
        ('1AA', 'A123456B', 'Edmund', 'Australia', 'Denmark'),
        ('1AA', 'A123456B', 'Edmund', 'Australia', 'France'),
        ('2CS', 'C435664C', 'Grace', 'Norway', NULL),
        ('3TG', 'G885595H', 'Rae', NULL, 'Japan')
    ;
    Select ID ,  IC ,  Name ,  UGCOS,MAX([MCOS1])[MCOS1],MAX([MCOS2])[MCOS2] from (
    select ID ,  IC ,  Name ,  UGCOS ,  MCOS,col,val,col +''+CAST(ROW_NUMBER()OVER(PARTITION BY ID ORDER BY col) AS VARCHAR)RN from @Table1
    CROSS APPLY (values('MCOS',MCOS))CS(col,val))T
    PIVOT (MAX(val) FOR RN IN ([MCOS1],[MCOS2]))PVT
    GROUP BY ID ,  IC ,  Name ,  UGCOS

答案 3 :(得分:0)

您是否总是最多有2行数据需要转换为列?如果是这样,那就是你;

CREATE TABLE #TableName (ID varchar(3), IC varchar(8), Name varchar(6), UCGOS varchar(9), MCOS varchar(7))
INSERT INTO #TableName
VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan')

SELECT DISTINCT a.ID
    ,a.IC
    ,a.NAME
    ,a.UCGOS
    ,b.Mcos1 MCOS
    ,c.Mcos2 MCOS1
FROM #TableName a
LEFT JOIN (
    SELECT ID
        ,MAX(MCOS) Mcos1
    FROM #TableName
    GROUP BY ID
    ) b ON a.ID = b.ID
LEFT JOIN (
    SELECT ID
        ,MIN(MCOS) Mcos2
    FROM #TableName
    GROUP BY ID
    ) c ON a.ID = c.ID
    AND (
        b.ID = c.ID
        AND b.Mcos1 <> c.Mcos2
        )

DROP TABLE #TableName

为您提供您所追求的结果。