需要帮助将多个SQL行动态组合到列中

问题描述 投票:0回答:1

我有一张桌子,有

P1_ID, P2_ID, Relationship_ID
1,21,3
1,32,3
2,45,2
2,65,1
3,98,3
3,94,4

我希望决赛桌看起来像:

P1_ID, P2_ID1, P2_ID2, RID1, RID2
 1    , 21    , 32    , 3   , 3
 2    , 45    , 65    , 2   , 1
 3    , 98    , 94    , 3   , 4

我不确定该朝哪个方向前进。我正在尝试使用枢轴,但似乎无法使其正常工作。也许我做错了。任何帮助都会很棒!

我是新手,如果我在帖子中犯了任何错误,请告诉我我会纠正。

sql sql-server
1个回答
0
投票

您可以为此使用条件聚合。这与您所说的输出内容不完全相同,因为数据的排序有点时髦。但这应该为您指明正确的方向。

declare @Something table
(
    P1_ID int
    , P2_ID int
    , Realationship_ID int
)

insert @Something values
(1,21,3)
, (1,32,3)
, (2,45,2)
, (2,65,1)
, (3,98,3)
, (3,94,4)

select P1_ID
    , P2_ID1 = MAX(Case when RowNum = 1 then P2_ID end)
    , P2_ID2 = max(case when RowNum = 2 then P2_ID end)
    , RID1 = MAX(Case when RowNum = 1 then Realationship_ID end)
    , RID2 = max(case when RowNum = 2 then Realationship_ID end)
from
(
    select *
        , RowNum = ROW_NUMBER() over(partition by s.P1_ID order by Realationship_ID)
    from @Something s
) x
group by x.P1_ID

-EDIT-

这里是一个完全动态的解决方案。我切换到使用临时表,因为表变量将超出动态sql的范围。显然,根据您的情况,您将使用持久表。这将按照P1_ID对输出进行排序,并按Realationship_ID对每一行中的列进行排序。

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

create table #Something
(
    P1_ID int
    , P2_ID int
    , Realationship_ID int
)

insert #Something values
(1,21,3)
, (1,32,3)
, (2,45,2)
, (2,65,1)
, (3,98,3)
, (3,94,4)
;

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by P1_ID order by P1_ID';
declare @StaticPortion nvarchar(2000) = 
'with OrderedResults as
(
    select *
        , RowNum = ROW_NUMBER() over(partition by s.P1_ID order by Realationship_ID)
    from #Something s
)
select P1_ID';

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 cross join 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 P2_ID end) as P2_ID' + CAST(N as varchar(6)) + CHAR(10) +
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then Realationship_ID end) as RID' + CAST(N as varchar(6)) + CHAR(10)
from cteTally t
where t.N <= 
(
    select top 1 Count(*)
    from #Something
    group by P1_ID
    order by COUNT(*) desc
)

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

exec sp_executesql @SqlToExecute
© www.soinside.com 2019 - 2024. All rights reserved.