我表中的几列似乎是
Id Code date latest
1 T 2014-10-04 0
2 B 2014-10-19 0
2 B 2014-10-26 0
1 S 2014-10-05 0
1 T 2014-10-06 0
1 T 2014-10-08 1
2 P 2014-10-27 1
我正在跟踪每个ID所做的所有更改。如果有任何更改,我会插入新行并更新最新值列。
我想要的是每个Id,我应该能够找到最新为0的最后一个代码。此外,该代码不应该等于现有代码(latest = 1)所以对于id = 1,answer不能< / p>
Id Code
1 T
至于id = 1
T是现有代码(latest = 1
)
理想情况下,我的输出应该如下:
Id Code
1 S
2 B
我想我可以为latest = 0
。
但是我如何确保它不应该等于现有代码值(latest = 1
)
答案 0 :(得分:0)
我认为以下是您想要的:
select t.*
from (select distinct on (code) id, code
from table t
where latest = 0
order by code, date desc
) t
where not exists (select 1 from table t2 where t2.id = t.id and t2.code = t.code and t2.latest = 1);
答案 1 :(得分:0)
我相信您应该拥有当前版本的数据,并且您应该创建另一个表,您可以在其中存储以前的修订版,具有Id
的外键。您的Id
无法满足具有此名称的列的一般期望。所以,理想情况下,你会:
Revisions(Id, myTableId, core, date, revision)
,其中Id
为auto_increment
primary key
,myTableId
将指向记录的Id
(1和示例中的2)insert into Revisions(myTableId, core, date, revision) select Id, core, date latest from MyTable where latest = 0
update Revisions r1 set r1.revision = (select count(*) from revisions r2 where r2.date < r1.date)
delete from MyTable where latest = 0
latest
列
从这里,您将始终可以选择倒数第二个版本,或倒数第二个等等,没有问题。请注意,我的代码建议在postgreSQL中可能是错误的语法,因为我从未使用它,但是这个想法也应该在那里工作。
答案 2 :(得分:0)
适用于 Postgres :
SELECT DISTINCT ON (t0.id)
t0.id, t0.code
FROM tbl t0
LEFT JOIN tbl t1 ON t1.code = t0.code
AND t1.id = t0.id
AND t1.latest = 1
WHERE t0.latest = 0
AND t1.code IS NULL
ORDER BY t0.id, t0.date DESC;
我使用LEFT JOIN
/ IS NULL
的组合删除latest = 1
行的兄弟。有多种方法可以做到这一点:
DISTINCT ON
的详细信息:
由于 Redshift 似乎不支持DISTINCT ON
:
WITH cte AS (
SELECT t0.*
FROM tbl t0
LEFT JOIN tbl t1 ON t1.code = t0.code
AND t1.id = t0.id
AND t1.latest = 1
WHERE t0.latest = 0
AND t1.id IS NULL
)
SELECT c0.id, c0.code
FROM cte c0
LEFT JOIN cte c1 ON c1.id = c0.id
AND c1.date > c0.date
WHERE c1.id IS NULL
ORDER BY c0.id;
SQL Fiddle显示两者。