将来自多个属性表的历史记录数据汇总在一起

时间:2019-05-16 21:34:05

标签: sql database oracle database-design

我有一组经过精心设计的数据库表,其中包含容器的数据。船只属性分为各自的表(船只名称,长度,马力等)。更新船只后,我们会将新记录的有效日期插入到适当的属性表中,以便我们保留历史记录。

我需要将此数据提取到一个平面对象中,该对象通过历史记录显示船只的外观。因此,如果名称和长度都在同一天进行编辑,则该天将只有一条记录。 请参考以下内容,以更好地解释现有数据和预期结果。

现有数据库表

Vessel  
|---------------------|------------------|------------------|  
|      vessel_id      |        CG#       |   Modified_Date  |  
|---------------------|------------------|------------------|  
|          1          |        123       |     01/01/2000   |  
|---------------------|------------------|------------------|  

Vessel_Name  
|---------------------|------------------|------------------|  
|      vessel_id      |      Name        |   Modified_Date  |  
|---------------------|------------------|------------------|  
|          1          |   Sea Queen      |     01/01/2000   |  
|---------------------|------------------|------------------|  
|          1          |   Sea King       |     01/01/2001   |  
|---------------------|------------------|------------------|  
|          1          |   Sea Goddess    |     03/01/2005   |  
|---------------------|------------------|------------------|  

Vessel_Horsepower  
|---------------------|------------------|------------------|  
|      vessel_id      |      HP          |   Modified_Date  |  
|---------------------|------------------|------------------|  
|          1          |       50         |     02/01/2000   |  
|---------------------|------------------|------------------|  
|          1          |       75         |     01/01/2003   |  
|---------------------|------------------|------------------|  
|          1          |      115         |     03/01/2005   |  
|---------------------|------------------|------------------|  

所需结果

Vessel_History  
|------------|------------|------------|------------|----------------|  
| vessel_id  |     CG#    |    name    |     HP     | effective_Date |  
|------------|------------|------------|------------|----------------|  
|     1      |     123    | Sea Queen  |    NULL    |   1/1/2000     |  
|------------|------------|------------|------------|----------------|  
|     1      |     123    | Sea Queen  |     50     |   2/1/2000     |  
|------------|------------|------------|------------|----------------|  
|     1      |     123    | Sea King   |     50     |   1/1/2001     |  
|------------|------------|------------|------------|----------------|  
|     1      |     123    | Sea King   |     75     |   1/1/2003     |  
|------------|------------|------------|------------|----------------|  
|     1      |     123    |Sea Goddess |     115    |   3/1/2005     |  
|------------|------------|------------|------------|----------------|  

我已经继承了该数据库,目前无法更改其设计。

1 个答案:

答案 0 :(得分:0)

-- Your Test Data
with vessel(id, cg, modified_date) as
 (select 1, 123, to_date('01012000', 'DDMMYYYY') from dual),
vessel_name(id, name, modified_date) as
 (select 1, 'Sea Queen', to_date('01012000', 'DDMMYYYY')
    from dual
  union all
  select 1, 'Sea King', to_date('01012001', 'DDMMYYYY')
    from dual
  union all
  select 1, 'Sea Goodess', to_date('03012005', 'DDMMYYYY')
    from dual),
vessel_horsepower(id, hp, modified_date) as
 (select 1, 50, to_date('02012000', 'DDMMYYYY')
    from dual
  union all
  select 1, 75, to_date('01012003', 'DDMMYYYY')
    from dual
  union all
  select 1, 110, to_date('03012005', 'DDMMYYYY')
    from dual)

-- Select:
select m.id,
       -- determine value of table "vessel" for current id, modified_date 
       (select cg
          from vessel n
         where n.id = m.id
           and n.modified_date =
               (select max(nn.modified_date)
                  from vessel nn
                 where nn.id = n.id
                   and nn.modified_date <= m.modified_date)),
       -- determine value of table "vessel_name" for current id, modified_date 
       (select name
          from vessel_name n
         where n.id = m.id
           and n.modified_date =
               (select max(nn.modified_date)
                  from vessel_name nn
                 where nn.id = n.id
                   and nn.modified_date <= m.modified_date)),
       -- determine value of table "vessel_horsepower" for current id, modified_date 
       (select hp
          from vessel_horsepower n
         where n.id = m.id
           and n.modified_date =
               (select max(nn.modified_date)
                  from vessel_horsepower nn
                 where nn.id = n.id
                   and nn.modified_date <= m.modified_date)),
       m.modified_date
  from -- collect all modified_dates of an id:
        (select v.id, v.modified_date
           from vessel v
         union
         select v.id, v.modified_date
           from vessel_name v
         union
         select v.id, v.modified_date
           from vessel_horsepower v) m;