多行成一行多列

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 应该是唯一的。由于它们是重复的,因此您将获得 null 以及值。您可以尝试嵌套旋转。此链接可能对您有所帮助link【参考方案3】:

我们可以在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 行变列(多行变成一行/多行合并成一行/多行合并成多列/合并行)

怎么将excel中两列转换成多行多列

C#将查询返回的数据(一行多列)怎么转换成一列多行dataTable?

hive如何实现多行转多列

sql中一对多关系的查询结果的多行转换成一行多列

oracle单行多列,拆分成多行