多行成一行多列

时间:2019-08-14 04:40:04

标签: sql sql-server tsql db2 transpose

我们需要将所有数字列出为一个平面数据集,我们该怎么做?

表名:电话

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

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

尝试按如下所示进行旋转:

     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>;

答案 2 :(得分:0)

我们可以尝试在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;

答案 3 :(得分:0)

您可以尝试一下。与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