假设您有一个名为 tracker 的表,其中包含以下记录。
issue_id | ingest_date | verb,status
10 2015-01-24 00:00:00 1,1
10 2015-01-25 00:00:00 2,2
10 2015-01-26 00:00:00 2,3
10 2015-01-27 00:00:00 3,4
11 2015-01-10 00:00:00 1,3
11 2015-01-11 00:00:00 2,4
我需要以下结果
10 2015-01-26 00:00:00 2,3
11 2015-01-11 00:00:00 2,4
我正在尝试这个查询
select *
from etl_change_fact
where ingest_date = (select max(ingest_date)
from etl_change_fact);
但是,这只给我
10 2015-01-26 00:00:00 2,3
这条记录。
但是,我想要所有唯一的记录(change_id)
(a) 最大(摄取日期)和
(b) 动词列优先级为(2 - 第一首选,1 - 第二首选,3 - 最后首选)
因此,我需要以下结果
10 2015-01-26 00:00:00 2,3
11 2015-01-11 00:00:00 2,4
请帮我高效查询。
附言: 我不会索引 ingest_date,因为我将在分布式计算设置中将其设置为“分发 key ”。 我是数据仓库和查询的新手。
因此,请帮助我优化方法来访问我的 TB 大小的数据库。
最佳答案
这是一个典型的“每组最多 n 个”问题。如果您在此处搜索此标签,您将获得大量解决方案 - 包括 MySQL。
对于 Postgres,最快的方法是使用 distinct on
(这是 SQL 语言的 Postgres 专有扩展)
select distinct on (issue_id) issue_id, ingest_date, verb, status
from etl_change_fact
order by issue_id,
case verb
when 2 then 1
when 1 then 2
else 3
end, ingest_date desc;
您可以增强原始查询以使用相关的子查询来实现相同的目的:
select f1.*
from etl_change_fact f1
where f1.ingest_date = (select max(f2.ingest_date)
from etl_change_fact f2
where f1.issue_id = f2.issue_id);
编辑
对于过时且不受支持的 Postgres 版本,您可能可以使用类似这样的方法:
select f1.*
from etl_change_fact f1
where f1.ingest_date = (select f2.ingest_date
from etl_change_fact f2
where f1.issue_id = f2.issue_id
order by case verb
when 2 then 1
when 1 then 2
else 3
end, ingest_date desc
limit 1);
SQLFiddle 示例:http://sqlfiddle.com/#!15/3bb05/1
关于postgresql - PostgreSQL 中的优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28297327/