SQL。根据日期联接3个或更多表中的记录

时间:2018-07-04 08:48:52

标签: sql join

我的表看起来像这样(只是一个例子):

表1:

TIME     |data1
1.01.2018|aaa
2.01.2018|bbb

表2:

TIME     |data2
1.01.2018|abcd
2.01.2018|cd

table3:

TIME     |data3
1.01.2018|
2.01.2018|d

现在我想做的是从table2中获取数据,并将其放在缺少记录的table1中。如果该日期所有表中都没有记录,则数据列中的数据为NULL。复制到table1的数据必须与table2中的日期相同。如果表1中没有与表2中相同的日期,则会创建该日期。

到目前为止,我已经尝试使用此代码,但是复制的数据无效。如果某些表中缺少日期,则会在时间列中创建该日期,但是数据列中的数据不正确。

    SELECT DISTINCT table1.time,table1.data,table2.time,table2.data,table3.time,table3.data
    FROM table1
    LEFT JOIN table2 ON table1.time=table2.time 
    LEFT JOIN table3 ON table1.time=table3.time 

编辑 这是输出的样子: 例如,表3中没有该日期的数据3的数据,因此该单元格为空。

TIME     |data1|data2|data3|
1.01.2018|aaa  |abcd |     |
2.01.2018|bbb  |  cd |   d |

5 个答案:

答案 0 :(得分:2)

您需要完全联接,而不是左联接。 (您未指定后端。此处示例使用MS SQL),即:

SELECT  
coalesce(table1."time",table2."time", table3."time") as "time",
         table1.data1,table2.data2,table3.data3
    FROM table1
    full JOIN table2 ON table1."time"=table2."time" 
    full JOIN table3 ON table1."time"=table3."time" ;

输出:

Time    data1   data2   data3
1.01.2018   aaa abcd    (null)
2.01.2018   bbb cd      d

编辑:代码中的不同之处建议您每天只需要一行。然后,不清楚应使用哪个列值。假设任何方法都可以,您可以像这样进行聚合:

SELECT  
coalesce(table1."time",table2."time", table3."time") as "time",
         max(table1.data1) as data1,
         max(table2.data2) as data2,
         max(table3.data3) as data3
    FROM table1
    full JOIN table2 ON table1."time"=table2."time" 
    full JOIN table3 ON table1."time"=table3."time" 
  group by coalesce(table1."time",table2."time", table3."time");

答案 1 :(得分:1)

使用

开始该过程
SELECT [DISTINCT] TIME FROM TABLE1
UNION [DISTINCT]
SELECT [DISTINCT] TIME FROM TABLE2
UNION [DISTINCT]
SELECT [DISTINCT] TIME FROM TABLE3

然后左键联接三个表。

答案 2 :(得分:0)

尝试一下:

with cte as (Select time from table1 union Select time from table2 union Select time from table3)
    SELECT cte.time,table1.data as data1,table2.data as data2,table3.data as data3
    FROM cte
    LEFT JOIN table1 ON table1.time=cte.time 
    LEFT JOIN table2 ON cte.time=table2.time 
    LEFT JOIN table3 ON cte.time=table3.time 

答案 3 :(得分:0)

在合并后应用简单的左联接。

DECLARE @t1 table
(
TIMEDate1 DATE
,Data1 VARCHAR(50)
)

DECLARE @t2 table
(
TIMEDate2 DATE
,Data2 VARCHAR(50)
)

DECLARE @t3 table
(
TIMEDate3 DATE
,Data3 VARCHAR(50)
)


insert @t1 (TIMEDate1,Data1 ) select getdate(),'aaa'
insert @t1 (TIMEDate1,Data1 ) select getdate()+1,'bbb'

insert @t2 (TIMEDate2,Data2 ) select getdate(),'abcd'
insert @t2 (TIMEDate2,Data2 ) select getdate()+1,'cd'

insert @t3 (TIMEDate3,Data3 ) select getdate(),''
 insert @t3 (TIMEDate3,Data3 ) select getdate()+1,'d'

SELECT t.TIMEDate,t1.Data1,t2.Data2,t3.Data3 
FROM (
SELECT distinct TIMEDate1  as  TIMEDate FROM @t1
UNION 
SELECT distinct TIMEDate2 as TIMEDate FROM @t2
UNION 
SELECT distinct TIMEDate3 as TIMEDate FROM @t3
) t
left JOIN @t1 t1 ON t1.TIMEDate1 = t.TIMEDate
left JOIN @t2 t2 ON t2.TIMEDate2 = t.TIMEDate
left JOIN @t3 t3 ON t3.TIMEDate3 = t.TIMEDate
--order by t1.TIMEDate1 asc

答案 4 :(得分:0)

下面的SQL只是将缺少的日期插入到Table1中的一种替代方法。

--
-- insert those into Table1 that are in Table2 but not in Table1
--
insert into Table1 ("time", data1)
select "time", data2
from Table2 as t2
where not exists
(
  select 1
  from Table1 as t1
  where t1."time" = t2."time"
);

--
-- insert those into Table1 that are in Table3 but not in Table1
--
insert into Table1 ("time", data1)
select "time", data3
from Table3 as t3
where not exists
(
  select 1
  from Table1 as t1
  where t1."time" = t3."time"
);

然后在所有这些之后添加Table1中仍然缺少的日期。
以下是MS SQL Server的示例:

;with RCTE_DATERANGE as 
( 
   select min([time]) as dt, max([time]) as max_dt
   from Table1
   union all 
   select dateadd(day, 1, dt), max_dt 
   from RCTE_DATERANGE where dt < max_dt 
) 
insert into Table1 ([time])
select dt 
from RCTE_DATERANGE AS rcte
where not exists
(
  select 1
  from Table1 as t1
  where t1.[time] = rcte.dt
);

-- Just checking
;with RCTE_DATERANGE as 
( 
   select min([time]) as dt, max([time]) as max_dt
   from Table1
   union all 
   select dateadd(day, 1, dt), max_dt 
   from RCTE_DATERANGE where dt < max_dt 
) 
select rcte.dt, t1.[time] as time1, t2.[time] as time2, t3.[time] as [time3], t1.data1, t2.data2, t3.data3  
from RCTE_DATERANGE AS rcte
full join Table1 t1 on t1.[time] = rcte.dt
full join Table2 t2 on t2.[time] = rcte.dt
full join Table3 t3 on t3.[time] = rcte.dt;