Sql 从多个属性表中收集历史数据
我有一套设计得非常糟糕的数据库表,其中包含船只的数据。船舶属性被拆分为各自的表格船舶名称、长度、马力等。当船舶更新时,我们会在相应的属性表格中插入一条新记录,并注明生效日期,以便我们可以保留历史记录 我需要将这些数据拉入一个平面对象,该对象显示船只在历史中的样子。因此,如果名称和长度都在同一天编辑,那么当天只有一条记录。 请参考以下内容,更好地解释现有数据和预期结果 现有数据库表 预期结果Sql 从多个属性表中收集历史数据,sql,database,oracle,database-design,Sql,Database,Oracle,Database Design,我有一套设计得非常糟糕的数据库表,其中包含船只的数据。船舶属性被拆分为各自的表格船舶名称、长度、马力等。当船舶更新时,我们会在相应的属性表格中插入一条新记录,并注明生效日期,以便我们可以保留历史记录 我需要将这些数据拉入一个平面对象,该对象显示船只在历史中的样子。因此,如果名称和长度都在同一天编辑,那么当天只有一条记录。 请参考以下内容,更好地解释现有数据和预期结果 现有数据库表 预期结果 我继承了此数据库,目前无法对其设计进行更改。帮助我们帮助您-请共享表定义、一些示例数据以及您希望获得的该示
我继承了此数据库,目前无法对其设计进行更改。帮助我们帮助您-请共享表定义、一些示例数据以及您希望获得的该示例结果。@Mureinik我添加了一个从原始帖子中删除的图表。
-- 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;
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 |
|------------|------------|------------|------------|----------------|
-- 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;