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
- Click here查看结果
如果你想要第二种指定格式,你可以使用下面的查询
;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
- Click here 查看结果
我在构建查询时遇到问题。在 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
- Click here查看结果
如果你想要第二种指定格式,你可以使用下面的查询
;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
- Click here 查看结果