在一张表中显示来自不同临时表的值

时间:2018-07-13 09:39:19

标签: sql sql-server

我的sql表如下:-

 CREATE TABLE #TmpA (
 Type1 Varchar(10),
 Col1 VARCHAR(10),
 Request INT,
 Due INT
  );

CREATE TABLE #TmpB (
 Type1 Varchar(10),
 Col1 VARCHAR(10),
 Request INT,
 Due INT );

CREATE TABLE #TmpC (
 Type1 Varchar(10),
 Col1 VARCHAR(10),
 Request INT,
 Due INT );

 INSERT INTO #TmpA VALUES('P', 'Name1',0,278),('P', 'Name2',10,89),('R', 'Name3',5,89)

 INSERT INTO #TmpB VALUES ('P', 'Name1',0,10),('P', 'Name2',1,78),('A', 'Name4',4,289 )

 INSERT INTO #TmpC VALUES ('P', 'Name1',54,67),('P', 'Name5',5,47),('A', 'Name6',3,90 )

SELECT * FROM #TmpA
SELECT * FROM #TmpB
SELECT * FROM #TmpC

我想将所有表合并到一个表中,因为我又创建了一个表#TmpD。我想以以下格式显示: enter image description here

在此示例中,#TmpD列必须是动态的,我已将其设为3,但也可以大于3或小于3。

3 个答案:

答案 0 :(得分:1)

使用动态数据透视表的另一种方法:

---- create new table #tmpD by using select ... into
select *
into #tmpD
from  
    (      
        select *, 1 as reqNr  from #TmpA union all
        select *, 2  from #tmpB union all
        select *, 3  from #tmpc 
    ) t

declare @cols_req as nvarchar(max)
     ,  @cols_req_max as nvarchar(max)
     ,  @cols_due as nvarchar(max)
     ,  @cols_due_max as nvarchar(max)
     ,  @query  as nvarchar(max)

select @cols_req = stuff((select distinct ',' + quotename('Request'+ cast(row_number() over(partition by col1, type1 order by type1, col1) as varchar(10))) from #tmpD for xml path(''), type ).value('.', 'nvarchar(max)') ,1,1,'')
select @cols_req_max = stuff((select distinct ',' + ('max(Request'+ cast(row_number() over(partition by col1, type1 order by type1, col1) as varchar(10)) +') as Request' + cast(row_number() over(partition by col1, type1 order by col1, type1) as varchar(10))) from #tmpD for xml path(''), type ).value('.', 'nvarchar(max)') ,1,1,'')
select @cols_due = stuff((select distinct ',' + quotename('Due'+ cast(row_number() over(partition by col1, type1 order by type1, col1) as varchar(10))) from #tmpD for xml path(''), type ).value('.', 'nvarchar(max)') ,1,1,'')
select @cols_due_max = stuff((select distinct ',' + ('max(Due'+ cast(row_number() over(partition by col1, type1 order by type1, col1) as varchar(10)) +') as Due' + cast(row_number() over(partition by col1, type1 order by col1, type1) as varchar(10))) from #tmpD for xml path(''), type ).value('.', 'nvarchar(max)') ,1,1,'')

set @query = '    select Type1, Col1, isnull(Request1, 0) Request1, isnull(Due1, 0) Duel1, isnull(Request2, 0) Request2, isnull(Due2, 0) Due2, isnull(Request3, 0) Request3, isnull(Due3, 0) Due3 
                  from (
                          select Type1, Col1, ' + @cols_req_max + ', ' + @cols_due_max + '
                          from 
                                (
                                    select  Type1
                                          , Col1
                                          , Request
                                          , Due
                                          , col_req = ''Request''+ cast(reqNR as varchar(10))
                                          , col_due = ''Due''+ cast(reqNR as varchar(10))
                                    from #tmpD 
                                ) x
                          pivot ( max(request) for col_req in (' + @cols_req + ') )p  
                          pivot ( max(due) for col_due in (' + @cols_due + ') ) q
                          group by Type1, Col1
                       ) t
              '
print @query
execute sp_executesql @query;

最初,我创建了一个新的临时表(#tmpD),在其中插入了所有三个初始表的行,以及一个名为'reqNr'的额外列,其中显示了哪个表是源表。

对于具有三个以上表的情况,只需调整将所有行插入#tmpD表中的初始语句,以同时包含其他表。

您可以查看有效的演示here

答案 1 :(得分:0)

SELECT  T.Col1, 
        ISNULL(A.Request,0) AS Request1,
        ISNULL(A.Due,0) AS Due1,
        ISNULL(B.Request,0) AS Request2,
        ISNULL(B.Due,0) AS Due2,
        ISNULL(C.Request,0) AS Request3,
        ISNULL(C.Due,0) AS Due3
FROM 
(
    SELECT Col1
    FROM #TmpA
    UNION 
    SELECT Col1
    FROM #TmpB
    UNION
    SELECT Col1
    FROM #TmpC
)T
LEFT JOIN #TmpA A
    ON A.Col1=T.Col1
LEFT JOIN #TmpB B
    ON B.Col1=T.Col1
LEFT JOIN #TmpC C
    ON C.Col1=T.Col1

答案 2 :(得分:0)

一种方法使用union all和聚合:

select type1, col1,
       max(request1) as request1, max(due1) as due1,
       max(request2) as request2, max(due2) as due2,
       max(request3) as request3, max(due3) as due3
from ((select type1, col1,
              request as request1, due as due1,
              0 as request2, 0 as due2,
              0 as request3, 0 as due3
       from #tmpa
      ) union all
      (select type1, col1,
              0 as request1, 0 as due1,
              request as request2, due as due2,
              0 as request3, 0 as due3
       from #tmpb
      ) union all
      (select type1, col1,
              0 as request1, 0 as due1,
              0 as request2, 0 as due2,
              request as request3, due as due3
       from #tmpc
      )
     ) abc
group by type1, col1;

另一种方法是full join,但这可能很棘手:

select a.type1, a.col1,
       coalesce(a.request, 0) as request1, coalesce(a.due, 0) as due1,
       coalesce(b.request, 0) as request2, coalesce(b.due, 0) as due2,
       coalesce(c.request, 0) as request3, coalesce(c.due, 0) as due3
from #tmpA a full join
     #tmpB b
     on b.type1 = a.type1 and b.col1 = a.col1 full join
     #tmpC c
     on c.type1 = coalesce(a.type1, b.type1) and
        c.col1 = coalesce(a.col1, b.col1);