【问题标题】:How to cross history when joining tables?加入表格时如何跨历史记录?
【发布时间】:2020-03-07 13:51:36
【问题描述】:

有两个表:

Table1(id, param1, param2, date_from, date_to):

(1, 'z', 55, '01.05.2010 12:30:20', '17.05.2010 13:10:14'),
(1, 'c', null, '17.05.2010 13:10:15', '18.01.2010 04:13:15'),
(1, 'c', 25, '18.01.2010 04:13:16', '01.01.9999 00:00:00');

Table2(id, param3, date_from, date_to):

(1, 15, '01.04.2010 12:30:20', '02.05.2010 13:10:14'),
(1, 35, '02.05.2010 13:10:15', '01.01.9999 00:00:00');

在合并2个表时,必须有字段包含每个参数的更改历史。那就是:

选择(id,param1,param2,param3,date_from,date_to):

(1, null, null, 10, '01.04.2010 12:30:20', '01.05.2010 12:30:19'),
(1, 'z', 55, 15, '01.05.2010 12:30:20', '02.05.2010 13:10:14'),
(1, 'z', 55, 35, '02.05.2010 13:10:15', '17.05.2010 13:10:14'),
(1, 'c', null, 35, '17.05.2010 13:10:15', '18.01.2010 04:13:15'),
(1, 'c', 25, 35, '18.01.2010 04:13:16', '01.01.9999 00:00:00');

如果两个表中的记录在时间上(或部分时间)不重叠,则应输出 null。

到目前为止我已经完成了:

SELECT a.id, param1, param2, param3, a.dfrom as afrom, a.dto as ato, b.dfrom as bfrom, b.dto as bto
FROM Table1 a LEFT JOIN Table2 b ON a.id = b.id
UNION
SELECT id, null as param1, null as param2, param3, null as afrom, null as bfrom, dfrom, dto
FROM Table2

然后我不明白该怎么做……

【问题讨论】:

  • 在第一个结果行中,不应该是15而不是10吗?
  • @Sergey 。 . .我建议你设置一个 dbfiddle 的某种形式。
  • 向大家解释你想要什么。例如:这个日期值来自哪里:“01.05.2010 12:30:19”?

标签: sql database postgresql


【解决方案1】:

解决这个问题的想法是将数据解构为为参数分配值的“事件”。然后,使用聚合和窗口函数重建历史。

因为您有合法的 NULL 值,这有点棘手,但我认为以下内容可以满足您的需求:

with t as (
      select t1.id, t1.param1, t1.param2, null as param3, t1.date_from, 1 as which
      from table1 t1
      union all
      select t2.id, null as param1, null as param2, t2.param3, t2.date_from, 2 as which
      from table2 t2
     )
select t.id, dfrom,
       lead(dfrom, 1, '9999-01-01'::timestamp) over (partition by id order by dfrom) as dto,
       max(param1) over (partition by param1_grp) as param1,
       max(param2) over (partition by param2_grp) as param2,
       max(param3) over (partition by param3_grp) as param3
from (select id, max(param1) as param1, max(param2) as param2,
             max(param3) as param3, dfrom,
             count(*) filter (where which = 1) over (partition by id order by dfrom) as param1_grp,
             count(*) filter (where which = 1) over (partition by id order by dfrom) as param2_grp,
             count(*) filter (where which = 2) over (partition by id order by dfrom) as param3_grp
      from t
      group by id, dfrom
     ) t

【讨论】:

  • 那条评论对任何人都没有帮助。
猜你喜欢
  • 1970-01-01
  • 2015-06-14
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 2018-03-19
  • 1970-01-01
相关资源
最近更新 更多