我的表格如下:
id
caseid
status
表中的示例数据:
1 10 open
2 10 published
3 10 reopened
4 11 open
5 11 contact
6 11 response
7 11 published
我需要获取最后状态为caseid
的所有published
。
因此,在上面的示例中,只会检索11
(因为caseid 10稍后会重新打开)。
查询会是什么样的?
PS
我正在使用PDO准备好的陈述。
答案 0 :(得分:4)
select caseid from data d1 where d1.status = 'published'
and not exists (select * from data d2 where d1.caseid = d2. caseid
and d2.id > d1.id)
为获得最佳性能,应将id和caseid列编入索引。
答案 1 :(得分:3)
select a.caseid
from
(select max(id) as id, caseid
from table
group by caseid)a --this would get the last entry for every caseid
inner join table b on (a.id=b.id)
where b.status = 'published'
答案 2 :(得分:1)
编辑:
抱歉 - 第一次大脑放屁:(
这样更好吗?
select a.caseid,a.status
from temp a
where a.id in
(select MAX(id) maxid from temp group by caseid)
and status='published'
答案 3 :(得分:1)
我会添加另一个查询,因为它是没有索引的最快的 - 它只需要一次顺序表扫描。比@ Florin的查询更简单,更快捷。
SELECT caseid
FROM tbl
GROUP BY caseid
HAVING max(id) = max(CASE WHEN status = 'published' THEN id ELSE NULL END);
然而,使用适当的索引@ Elroy的解决方案要快得多。我实际上运行了一个类似真实生活表的快速基准来验证这一点 适当的索引:
CREATE INDEX tbl_id_idx ON tbl (id);
此partial index可获得最佳效果:
CREATE INDEX tbl_status_published_idx ON tbl (id) WHERE status = 'published';
此查询不需要任何其他索引。特别是,caseid
上的附加索引是没有用的。始终认为索引维护也会带来成本 - 特别是如果表格写得很多的话。
这可能会随PostgreSQL 9.2中的覆盖索引(“仅索引扫描”)而改变。我写了more about that in a recent answer on dba.SE。
尝试EXPLAIN ANALYZE进行验证。