SQLSERVER即使没有足够的行,也要将行选为列

时间:2015-01-23 08:38:42

标签: sql-server-2008 crosstab

构建查询时遇到问题。在stackoverflow上搜索后,我想我需要一个交叉表。但我不知道到底是什么。我想如果我向您展示我的问题的简化版本会更快。如果你能指出我正确的方向,我会很高兴的。

这是数据的示例:

ColumnIDToGroup  Value
-----------------------
  1              AAAA
  1              BBBB
  2              AAAA
  2              BBBB
  2              CCCC

我需要构建一个查询来获取这种格式的数据:

ColumnIDToGroup  Value1  Value2   Value3  Value4  Value5
------------------------------------------------------------
  1              AAAA     BBBB   'Empty'  'Empty' 'Empty'
  2              AAAA     BBBB    CCCC    'Empty' 'Empty'

作为一个workarround,我可以接受这个输出,如果它很容易构建(当一个值不为null时,它总是具有相同的大小)

ColumnIDToGroup      ValueConcat  
-------------------------------------
  1              AAAABBBB************
  2              AAAABBBBCCCC********

1 个答案:

答案 0 :(得分:1)

样本表

CREATE TABLE #TEMP(ColumnIDToGroup INT,Value VARCHAR(30))

INSERT INTO #TEMP
SELECT  1,             'AAAA'
UNION ALL
 SELECT   1,              'BBBB'
UNION ALL
 SELECT   2,              'AAAA'
UNION ALL
 SELECT   2,              'BBBB'
UNION ALL
SELECT    2,              'CCCC'

现在从表中选择行,为Value1,Value2等创建一个列,并为UN4选择Value4,Value5的额外列,并将文本设置为Empty。

SELECT *,
'Value'+CAST(ROW_NUMBER() OVER(PARTITION BY  ColumnIDToGroup ORDER BY VALUE)AS VARCHAR(3)) COL
INTO #NEWTABLE
FROM #TEMP
UNION ALL
SELECT 1,'Empty','Value3'
UNION ALL
SELECT 2,'Empty','Value3'
UNION ALL
SELECT 1,'Empty','Value4'
UNION ALL
SELECT 2,'Empty','Value4'
UNION ALL
SELECT 1,'Empty','Value5'
UNION ALL
SELECT 2,'Empty','Value5'

现在获取pivot

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + COL + ']', '[' + COL + ']')
               FROM    (SELECT DISTINCT COL FROM #NEWTABLE) PV 
               ORDER BY COL

现在转动查询

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT *   
                 FROM #NEWTABLE
             ) x
             PIVOT 
             (
                 MIN(VALUE)
                 FOR COL IN (' + @cols + ')
            ) p
            ORDER BY ColumnIDToGroup;' 

EXEC SP_EXECUTESQL @query

如果您想要第二种指定格式,可以使用以下查询

;WITH CTE AS
(
    SELECT *        
    FROM #TEMP
    UNION ALL
    SELECT 1,'****'
    UNION ALL
    SELECT 2,'****'
    UNION ALL
    SELECT 1,'****'
    UNION ALL
    SELECT 2,'****'
    UNION ALL
    SELECT 1,'****'
    UNION ALL
    SELECT 2,'****'
    UNION ALL
    SELECT 1,'****'
    UNION ALL
    SELECT 1,'***'
)
SELECT  DISTINCT C2.ColumnIDToGroup,  
-- Convert to single row for each ColumnIDToGroup
        SUBSTRING(
        (SELECT ' ' + CTE.VALUE
        FROM CTE 
        WHERE C2.ColumnIDToGroup=ColumnIDToGroup
        ORDER BY 
        CASE WHEN CTE.VALUE = 'AAAA' THEN 1
             WHEN CTE.VALUE = 'BBBB' THEN 2
             WHEN CTE.VALUE = 'CCCC' THEN 3
        ELSE 4
        END
        FOR XML PATH('')),2,200000) ValueConcat 
        FROM CTE C2