【问题标题】: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。请仅使用相关标签。

标签: sql sql-server tsql db2 transpose


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-09
        • 1970-01-01
        • 1970-01-01
        • 2012-01-01
        相关资源
        最近更新 更多