多行成一行多列
Posted
技术标签:
【中文标题】多行成一行多列【英文标题】:Multiple Rows into One Row multiple columns 【发布时间】:2019-08-14 04:40:04 【问题描述】:我们需要将所有数字作为一个平面数据集列出,我们该怎么做?
表格名称:电话
ID TYPE NUMBER
==================================
123 MN 042153939
123 HN 2242116
123 MN 1234567890
123 HN 12345678
Create Table Telephone
(
ID Integer,
Type char(3),
Number Varchar(20)
);
insert into Telephone values
(123, 'MN', '042153939'),
(123, 'HN', '2242116'),
(123, 'MN', '1234567890'),
(123, 'HN', '12345678');
我希望 SQL 以这种格式返回数据
ID MN#1 Mn#2 HN#1 HN#2
================================================
123 042153939 1234567890 2242116 12345678
【问题讨论】:
提示使用pivot
。正如Multiple Rows into One Row Single Column
所述,即使您的标题也不正确,而实际上您需要将行转换为列。请发布您迄今为止尝试过的内容
SQL Server 不是 DB2。请仅使用相关标签。
【参考方案1】:
动态方法
初始化
DROP TABLE IF EXISTS #Telephone;
CREATE TABLE #Telephone(ID INT,Type CHAR(3),Number VARCHAR(20));
INSERT INTO #Telephone (ID,Type,Number) VALUES
(123, 'MN', '042153939'),
(123, 'HN', '2242116'),
(123, 'MN', '1234567890'),
(123, 'HN', '12345678');
代码
DECLARE @ColumnList NVARCHAR(MAX);
SELECT @ColumnList = STUFF((SELECT ',[' + RTRIM(t.[Type]) + '#'
+ CONVERT(NVARCHAR(255),ROW_NUMBER()OVER(PARTITION BY t.[Type] ORDER BY t.ID)) + ']'
FROM #Telephone t FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'')
;
DECLARE @sql NVARCHAR(MAX) = '';
SET @sql = N'
SELECT ID,' + @ColumnList + N'
FROM (
SELECT t.ID,t.Number, RTRIM(t.[Type]) + ''#'' + CONVERT(NVARCHAR(255),ROW_NUMBER()OVER(PARTITION BY t.[Type] ORDER BY t.ID)) AS [Type]
FROM #Telephone t
) a
PIVOT(MAX(a.Number) FOR a.Type IN (' + @ColumnList + N')) p
'
;
--PRINT @sql
IF @sql IS NOT NULL EXEC(@sql);
【讨论】:
【参考方案2】:尝试如下旋转:
SELECT first_column AS <first_column_alias>,
[pivot_value1], [pivot_value2], ... [pivot_value_n]
FROM
(<source_table>) AS <source_table_alias>
PIVOT
(
aggregate_function(<aggregate_column>)
FOR <pivot_column> IN ([pivot_value1], [pivot_value2], ... [pivot_value_n])
) AS <pivot_table_alias>;
【讨论】:
我试过这个.... SELECT * FROM TELEPHONE PIVOT( min(NUMBER) FOR TYPE in ([MN],[HN],[WN])) AS MYNUMBERS WHERE id= 123;结果:ID MN HN WN 123 042153939 12345678(空) for我们可以在ROW_NUMBER()
的帮助下尝试使用透视查询:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY TYPE DESC, NUMBER) rn
FROM Telephone
)
SELECT
ID,
MAX(CASE WHEN rn = 1 THEN NUMBER END) AS [MN#1],
MAX(CASE WHEN rn = 2 THEN NUMBER END) AS [MN#2],
MAX(CASE WHEN rn = 3 THEN NUMBER END) AS [HN#3],
MAX(CASE WHEN rn = 4 THEN NUMBER END) AS [HN#4]
FROM cte
GROUP BY ID;
【讨论】:
【参考方案4】:你可以试试这个。 row_number()
和 pivot
。
有关pivot
的更多信息,您可以找到此链接PIVOT。
; with cte as (
select row_number() over (partition by type order by id ) as Slno, * from Telephone
)
, ct as (
select id, type + '#' + cast(slno as varchar(5)) as Type, values from cte
)
select * from (
select * from ct
) as d
pivot
( max(values) for type in ( [MN#1],[Mn#2],[HN#1],[HN#2] )
) as p
【讨论】:
以上是关于多行成一行多列的主要内容,如果未能解决你的问题,请参考以下文章
mysql 行变列(多行变成一行/多行合并成一行/多行合并成多列/合并行)