它看起来像你保持基于时间的对象实例在statut_existenta_pf
表。
我用下面的测试平台:
CREATE TABLE statut_existenta_pf (
se_id int4,
se_id_pf int4,
se_id_statut int2,
se_data_inceput date,
se_data_sfarsit date
); -- the rest fields are irrelevant for this example
CREATE TABLE nom_statut_existenta (
id int2,
ne_denumire varchar(30)
); -- my wild guess bout this table
CREATE TABLE persoane_fizice (
pf_id int4,
pf_name varchar(60)
); --- same here, irrelevant for the example
与下面的测试数据:
INSERT INTO nom_statut_existenta VALUES
(1, 'Status: Vive'), (2, 'Status: Morto');
INSERT INTO persoane_fizice VALUES (3489, 'Giuseppe Garibaldi');
INSERT INTO statut_existenta_pf VALUES
(4275, 3489, 2, '2012-04-18', '2012-05-18'),
(3669, 3489, 1, '2010-03-31', NULL);
现在,你正在寻找在这个基于时间的一系列的当前对象。你的逻辑似乎是以下情况:
- 如果
se_data_inceput
是NULL
(我把这个列instance_start_date
),然后下载最新的版本为给定persoane_fizice
的价值;
- 如果
se_data_sfarsit
是NULL
(instance_end_date
我相信)然后再次,得到最新版本的值;
- 如果两列均为
NOT NULL
,则获取在这些日期之间的修订值。
您在设置中没有提到任何约束条件,但我认为具有重叠日期范围的多个条目是非法的。
以下是我改写了你的初始查询,得到正确的结果:
WITH max_se_id AS (
SELECT se_id_pf, max(se_id) se_id_max FROM statut_existenta_pf
GROUP BY se_id_pf
)
SELECT p.*, se.se_id_statut, ne.ne_denumire
FROM persoane_fizice p
JOIN statut_existenta_pf se ON se.se_id_pf = p.pf_id
JOIN nom_statut_existenta ne ON ne.id = se.se_id_statut
JOIN max_se_id mse ON se.se_id_pf = mse.se_id_pf
WHERE p.pf_id = :id_pf
AND se.se_id_statut IN
(CASE
WHEN se_data_inceput IS NULL THEN mse.se_id_max
WHEN se_data_inceput IS NOT NULL AND se_data_sfarsit IS NULL THEN mse.se_id_max
ELSE se_id_statut
END) ;
但这个查询产生不正确的结果,对于给定的实验平台,它将返回最高se_id
修改,尽管它有启动在未来的时间。
我用同样的方法,以保持对象的历史数据库,我建议使用这样的查询,而不是:
SELECT p.*, se.se_id_statut, ne.ne_denumire
FROM persoane_fizice p
JOIN statut_existenta_pf se ON se.se_id_pf = p.pf_id
JOIN nom_statut_existenta ne ON ne.id = se.se_id_statut
WHERE p.pf_id = :id_pf
AND statement_timestamp() BETWEEN coalesce(se.se_data_inceput, now())
AND coalesce(se.se_data_sfarsit, clock_timestamp());
如果您在se_data_inceput
+ se_data_sfarsit
列不重叠的日期,此查询将产生当前活动的行。
我使用:
now()
作为se_data_inceput
的默认值,这会产生当前事务的开始时间;
statement_timestamp()
在时间当前点和
clock_timestamp()
作为se_data_sfarsit
默认。
通过这种组合,您可以始终期待您的查询从历史记录表中返回当前对象实例。
我希望我的假设是正确的。