SQLSERVER Select 行作为列,即使没有足够的行

SQLSERVER Select rows as columns even if there is no enough rows

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

这是数据示例:

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'

作为解决方法,我可以接受这个输出,如果它易于构建(当值不为空时,它总是具有相同的大小)

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

样本TABLE

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'

现在 select 来自 table 的行,为 Value1、Value2 等创建一个列,并 select 通过 UNION all 为 Value4、Value5 创建额外的列,并将文本设置为空.

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'

现在获取数据透视表的列

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