【问题标题】:Is there a join in sql that will fill in missing data of one table to the other?sql中是否存在将一个表的缺失数据填充到另一个表的连接?
【发布时间】:2019-12-27 13:26:07
【问题描述】:

我想从我创建的日期表中填写一个表中缺少的日期。

我有所有日期的第一个表是这个:

Dates
01/11/2018
02/11/2018
03/11/2018

我的数据的第二个表是这个:

Name    Value   Date
Go        1     01/11/2018
Go        3     02/11/2018
Ma        2     03/11/2018

我的最终输出应该是这样的:

Name    Value   Date
Go        1     01/11/2018
Go        3     02/11/2018
Go      null    03/11/2018
Ma      null    01/11/2018
Ma      null    02/11/2018
Ma        2     03/11/2018

我尝试了完整的外部连接,但没有成功:

select b.name, a.d_date, b.value
from date_month a 
full outer join namevalue b on a.d_date=b.d_date;

datemonth 是带有日期的表,namevalue 是带有名称的表。包含名称的表中至少有 300,000 个名称以及日期和值。

【问题讨论】:

标签: sql oracle date join outer-join


【解决方案1】:

分区外连接是填补稀疏数据空白的好方法。此连接允许我们根据列中的值重复连接。这种方法比常规外连接连接更多,但比交叉连接少得多,并且应该比交叉连接解决方​​案更有效。

select name, value, dates.the_date
from dates
left join my_data
    partition by (my_data.name)
    on dates.the_date = my_data.the_date
order by name, the_date;

NAME  VALUE  THE_DATE
----  -----  --------
Go        1  2018-01-11
Go        3  2018-02-11
Go           2018-03-11
Ma           2018-01-11
Ma           2018-02-11
Ma        2  2018-03-11

示例架构:

create table dates as
select date '2018-01-11' the_date from dual union all
select date '2018-02-11' the_date from dual union all
select date '2018-03-11' the_date from dual;

create table my_data as
select 'Go' name, '1' value, date '2018-01-11' the_date from dual union all
select 'Go' name, '3' value, date '2018-02-11' the_date from dual union all
select 'Ma' name, '2' value, date '2018-03-11' the_date from dual;

【讨论】:

    【解决方案2】:

    在 SQLite3 上尝试过(如果需要,进行相应调整)。

    -- setup test tables & data
    create table Dates(d);
    insert into dates values
    ('2018-11-01'),
    ('2018-11-02'),
    ('2018-11-03');
    
    --The second table with my data is this one
    create table dat(name,val,d);
    insert into dat values
    ('Go',1,'2018-11-01'),
    ('Go',3,'2018-11-02'),
    ('Ma',2,'2018-11-03');
    

    查询是:

    select name,val,d
      from (select distinct name,dates.d from dat join dates)
      left join dat using(name,d);
    

    【讨论】:

      【解决方案3】:

      您需要使用CROSS JOIN 创建一个包含 2 个名称 x 3 个日期 = 6 行的结果。然后做一个LEFT JOIN:

      SELECT all_names.name, date_month.date, namevalue.value
      FROM (SELECT DISTINCT name FROM namevalue) AS all_names
      CROSS JOIN date_month
      LEFT JOIN namevalue ON all_names.name = namevalue.name
                         AND date_month.date = namevalue.date
      

      【讨论】:

      • 非常好的和简单的解决方案。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 2020-06-07
      • 2021-09-05
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多