使用来自许多不同日期的不同表创建单个时间序列主表SQL Server / SSMS18

问题描述

我试图通过搜索网络上的文章和建议(例如INSERT,ALTER TABLE,MERGE,COALESCE,INSERT INTO SELECT)来找到答案。使用FULL JOIN或UNION ALL的建议接近要求,但是添加到表中的新字段需要附加到其对应的“ id”上,而不是如图所示的新记录(表C):Creating table from two different tables sql

SSMS2018将用于使用来自不同表的数据创建时间序列。每个日期都有多个具有不同字段的表。所有表中都存在“ id”字段(仅供参考:“ id”是公司的ID号)。

步骤:

  1. 需要在给定日期将所有字段组合到一个新表中。

  2. 需要使用所有日期和所有字段的数据创建一个主表(注意:可能会在日期之间添加新的“ id”或删除现有的“ id”)。目标是能够分析按“ id”分组的所有日期中每个字段的值(请参见下面的示例)。

问题:

  1. SSMS '18中的哪些sql语句用于执行上述步骤?
  2. 是否可以使用JOIN或其他sql函数来执行步骤2?

示例:

第1步:将表2中的字段追加到表1

表1

date        id  field1  field2          Table 2 date    id  field5  field6
20191231    a1    4      4                     20191231 a1    9         5
20191231    b5    4     10                     20191231 b5    8         8
20191231    c9    2     9                      20191231 c9    9        10

表1(修订版)

date        id  field1  field2  field5  field6                  
20191231    a1    4        4       9       5                    
20191231    b5    4       10       8       8                    
20191231    c9    2        9       9      10                    

步骤2:将表1(经修订)与表4(先前使用步骤1创建表4)合并/合并,以在“新表”中创建时间序列。

表4

date        id  field1  field2  field5  field6                  
20190930    a1    1       7        0      7                 
20190930    b5    3       2        6      1                 
20190930    c9    5      10        4      6                 
20190930    d11   0       5        3      7                 
                                        

新表格

date        id  field1  field2  field5  field6                  
20190930    a1     1      7        0      7                 
20191231    a1     4      4        9      5                 
20190930    b5     3      2        6      1                 
20191231    b5     4     10        8      8                 
20190930    c9     5     10        4      6                 
20191231    c9     2      9        9     10                 
20190930    d11    0      5        3      7                 
20191231    d11  NULL   NULL    NULL    NULL                    

解决方法

代替从Table2到Table1等的“附加字段”,然后创建一个主表,关系方法是将列的可变列表转换为具有固定列数的可变行。这意味着将每个表直接“取消透视”到标准化的Test_Main表中。 “新表”输出可以通过查询使用条件聚合来产生。

数据

drop table if exists #tTEST1;
go
select * INTO #tTEST1 from (values 
('20191231','a1',4,4),('20191231','b5',10),'c9',2,9)) V(mdate,id,field1,field2);

drop table if exists #tTEST2;
go
select * INTO #tTEST2 from (values 
('20191231',9,5),8,8),10)) V(mdate,field5,field6);

drop table if exists #tTEST4;
go
select * INTO #tTEST4 from (values 
('20191230',1,7,7),('20191230',3,6,1),5,10,6),'d11',7)) V(mdate,field2,field6);

主表的DDL

drop table if exists #tTEST_Main;
go
create table #tTEST_Main(
  id              varchar(10) not null,mdate           date not null,field_name      varchar(100) not null,series_val      int not null,constraint
    unq_tm_id_m_fn unique(id,mdate,field_name));

取消查询以填充Test_Main表

insert #tTEST_Main(id,field_name,series_val)
select v.*
from #tTEST1 t1
     cross apply
     (values (id,'field1',field1),(id,'field2',field2)) v(id,series_val);

insert #tTEST_Main(id,series_val)
select v.*
from #tTEST2 t2
     cross apply
     (values (id,'field5',field5),'field6',field6)) v(id,series_val)
select v.*
from #tTEST4 t4
     cross apply
     (values (id,field2),series_val);

查询以输出“新表”结果

select id,max(case when field_name='field1' then series_val else 0 end) field1,max(case when field_name='field2' then series_val else 0 end) field2,max(case when field_name='field5' then series_val else 0 end) field5,max(case when field_name='field6' then series_val else 0 end) field6
from #tTEST_Main
group by id,mdate;

输出

id  mdate       field1  field2  field5  field6
a1  2019-12-30  1       7       0       7
a1  2019-12-31  4       4       9       5
b5  2019-12-30  3       2       6       1
b5  2019-12-31  4       10      8       8
c9  2019-12-30  5       10      4       6
c9  2019-12-31  2       9       9       10
d11 2019-12-30  0       5       3       7