该查询可以像这样工作:
SELECt a.*FROM article aLEFT JOIN ( SELECt DISTINCT ON (article_id) article_id, value FROM metrics m WHERe name = 'score' ORDER BY article_id, date_created DESC ) m ON m.metrics_id = a.metrics_idORDER BY m.value DESC;
首先 ,检索“最近”
value的
name = 'score'每一篇文章中的子查询
m。在此相关答案中对所用技术的更多说明:
- 在每个GROUP BY组中选择第一行?
但是,您似乎是一个非常基本的误解的受害者:
但我只想对任何一篇文章使用最早发现的(最新的)“评分”。指标模型具有一个default_scope,以确保按DESCending排序。
有 没有“自然秩序” 在表中。在中
SELECT,您需要
ORDER BY定义明确的条件。出于此查询的目的,我假设使用column
metrics.date_created。如果您一无所获,则 无法 定义“最新”,并被迫从多个限定行退回到任意选择:
ORDER BY article_id
这是 不 可靠的。Postgres将选择一行。可能会随着对表的任何更新或查询计划中的任何更改而更改。
接下来 ,
LEFT JOIN到表
article和
ORDER BY value。
NULL排在最后,因此没有合格价值的文章排在最后。
注意:一些不太聪明的ORM(恐怕Ruby的ActiveRecord就是其中之一)使用非描述性和非区别性 id
作为主键的名称。您必须适应您未提供的实际列名。
表现
应该得体。就Postgres而言,这是一个“简单”的查询。表上的部分多列索引
metrics可以使其更快:
CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created)WHERe name = 'score';
列按此顺序。在PostgreSQL 9.2+中,您可以添加列值以使仅索引扫描成为可能:
CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created, value)WHERe name = 'score';



