我有一个包含导入文件索引的表,其中包含每个导入文件的日期和分支。
现在我需要对多个分支进行合并,因此,当我们有假期时,我必须复制来自某些分支的信息,以便数据保持一致,基本上我需要用最新的可用信息填补这些空白
我尝试使用排名进行一些自我加入,以便在它们之间切换并获取以前的数据,但它不起作用。
我所拥有的是一张桌子:
rundate, branch, imported
2015-04-01, PL1, TRUE
2015-04-01, ES1, TRUE
2015-04-01, CZ4, TRUE
2015-04-02, PL1, TRUE
2015-04-02, ES1, TRUE
2015-04-02, CZ4, TRUE
2015-04-03, ES1, TRUE
2015-04-03, CZ4, TRUE
在这个例子中,我想做一个返回的查询:
gap_date, branch, real_date
2015-04-03, PL1, 2015-04-02
此表非常小(几千行),因此,性能不应该是一个大问题。
关于如何实现这一点的任何想法?
现在我使用的函数接收间隙日期的rundate和branch作为参数,并在作为参数传递的日期之前回答最新的函数(使用max(rundate),其中rundate< ='$ 1')
谢谢!
答案 0 :(得分:1)
您可以使用outer join
,subquery
和cross join
:
架构:
create table tbl(rundate date,
branch varchar(10),
imported bool);
insert into tbl values('2015-04-01', 'PL1', TRUE),
('2015-04-01', 'ES1', TRUE),
('2015-04-01', 'CZ4', TRUE),
('2015-04-02', 'PL1', TRUE),
('2015-04-02', 'ES1', TRUE),
('2015-04-02', 'CZ4', TRUE),
('2015-04-03', 'ES1', TRUE),
('2015-04-03', 'CZ4', TRUE);
查询:
select q.rundate as gap_date,q.branch,
(select max(tt.rundate)
from tbl tt
where tt.rundate<q.rundate and tt.branch=q.branch)
as real_date
from tbl t
right outer join(
select rundate,branch from (
select distinct rundate from tbl) t1
cross join (
select distinct branch from tbl)t2
)q
on t.rundate=q.rundate and t.branch=q.branch
where t.branch is null
结果:
gap_date branch real_date
2015-04-03 PL1 2015-04-02
答案 1 :(得分:0)
你必须在一组中选择所有独特的日期,在另一组中选择所有独特的分支 - 制作它的笛卡尔产品 - 然后你可以检查你有差距的组合......这就是我的意思:
CREATE TEMPORARY TABLE _matrix
SELECT
t1.rundate,
t2.branch
(SELECT DISTINCT rundate FROM yourtable) t1,
(SELECT DISTINCT branch FROM yourtable) t2
然后你可以使用LEFT JOIN和“WHERE ... IS NULL”语句找到空白:
SELECT
m.rundate,
m.branch
FROM _matrix m
LEFT JOIN yourtable yt ON(yt.rundate = m.rundate AND yt.branch = m.branch)
WHERE yt.rundate IS NULL
当然,没有临时表也可以实现同样的效果 - 只使用子查询。特别是当表演并不重要时。
答案 2 :(得分:0)
这是来自@voycheck 的carthesian product of both domains
解决方案,除了实际存在的记录。
WITH br AS (
SELECT DISTINCT branch AS branch FROM tbl
)
, mima AS (
SELECT MIN(rundate) as mi
, MAX(rundate) as ma
FROM tbl)
, rng AS (
SELECT generate_series( mima.mi, mima.ma, '1 day'::interval)::date AS rundate
FROM mima
)
SELECT * FROM rng
JOIN br ON NOT EXISTS ( -- cartesian product EXCEPT
SELECT *
FROM tbl t
WHERE t.branch = br.branch
AND t.rundate = rng.rundate
)
;