SQL Server 2016:使用不同的迭代将多行转换为列

SQL Server 2016:使用不同的迭代将多行转换为列,sql,sql-server,sql-server-2016,Sql,Sql Server,Sql Server 2016,我有一个表,它有许多针对唯一成员ID的保险。如果有多个InsuranceNo,我希望InsuranceNo移到一列,因此最终每个MemberID有一行,该ID的InsuranceNo的所有迭代都作为一列 MemberID InsuranceNo -------------------------- 123456 dser 124571 jklh 123456 abcd 我希望它看起来像这样: MemberID

我有一个表,它有许多针对唯一成员ID的保险。如果有多个InsuranceNo,我希望InsuranceNo移到一列,因此最终每个MemberID有一行,该ID的InsuranceNo的所有迭代都作为一列

MemberID       InsuranceNo
--------------------------
123456            dser
124571            jklh
123456            abcd
我希望它看起来像这样:

MemberID       InsuranceNo1             InsuranceNo2
-----------------------------------------------------
123456            dser                  abcd
124571            jklh
Select *
 From (
        Select MemberID
              ,Item     = concat('InsuranceNo',row_number() over (Partition By MemberID Order By (Select NULL)))
              ,Value    = InsuranceNo
         From YourTable
      ) A
 Pivot (max([Value]) For [Item] in ([InsuranceNo1],[InsuranceNo2]) ) p

谢谢大家!

与动态轴相比,我更喜欢动态交叉表。我发现语法远没有那么迟钝,如果您需要添加额外的列,它非常简单。这是我将着手解决的问题。当然,在您的情况下,您不需要临时表,因为您有一个实际的表要使用

if OBJECT_ID('tempdb..#Something') is not null
    drop table #Something

create table #Something
(
    MemberID int
    , InsuranceNo varchar(10)
)

insert #Something values
(123456, 'dser')
, (124571, 'jklh')
, (123456, 'abcd')

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as
    (
        select *, ROW_NUMBER() over(partition by MemberID order by InsuranceNo) as RowNum
        from #Something
    )
    select MemberID';

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by MemberID order by MemberID';

with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
cteTally(N) AS 
(
    SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2
)

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then InsuranceNo end) as InsuranceNo' + CAST(N as varchar(6)) + CHAR(10)
from cteTally t
where t.N <= 
(
    select top 1 Count(*)
    from #Something
    group by MemberID
    order by COUNT(*) desc
)
select @StaticPortion + @DynamicPortion + @FinalStaticPortion

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
exec sp_executesql @SqlToExecute

还有一个选择。。。只需将表更改为实际的表名

范例

返回

如果它有助于您了解PIVOT,则生成的SQL如下所示:

MemberID       InsuranceNo1             InsuranceNo2
-----------------------------------------------------
123456            dser                  abcd
124571            jklh
Select *
 From (
        Select MemberID
              ,Item     = concat('InsuranceNo',row_number() over (Partition By MemberID Order By (Select NULL)))
              ,Value    = InsuranceNo
         From YourTable
      ) A
 Pivot (max([Value]) For [Item] in ([InsuranceNo1],[InsuranceNo2]) ) p

行数和案例表达式每个唯一成员可以拥有多少保险号码/无限数量的保险号码搜索动态数据透视您提前知道最大保险号码吗?还是说这需要有活力?@Erinager很乐意帮忙