1

在 Postgres 9.4 中,我有一个表格,其中包含不同发件人发送的用户电子邮件。我需要生成最近不同发件人的列表,我正在使用以下查询:

SELECT DISTINCT ON (tableA.senderName) 
       tableA.senderName,tableA.received,tableA.someOtherColumn
FROM tableA 
WHERE tableA.received BETWEEN timeA AND timeB
ORDER BY tableA.senderName,tableA.received DESC

由于tableA包含所有发件人的所有消息,因此此查询仅提供不同发件人的最新消息,并且效果很好。

实际上,我在一个视图中有整个查询(除了WHERE子句,因为timeAtimeB每次都不同),然后我只是SELECT *从这个视图中使用特定的timeA和子句。timeBWHERE

现在考虑以下查询:

SELECT SUM(ts_rank_cd(tableA.precompTSVector,constantTSQuery)) AS score 
FROM tableA 
WHERE tableA.precomTSVector @@ constantTSQuery
AND tableA.sender = someParticularSender
AND tableA.received BETWEEN timeA AND timeB

它给出了在给定时间范围内针对特定发件人的所有消息搜索某些恒定 TS 查询的总分。

我想将此查询(可能作为子查询)合并到我的视图中,以便我还可以看到每个不同发件人的“分数”。明显的问题是“分数查询”依赖于实际timeA并且timeB在 WHERE 子句中。在查询视图本身之前,这些时间是未知的。

编辑:一个不同的问题是someOtherColumn在第一个查询中也被选中(可能还有其他一些我也想合并到视图中的列) - 因为正在使用聚合函数。

任何想法如何实现这一目标?或者也许欢迎一些不同的方法!

4

1 回答 1

1
SELECT DISTINCT ON (senderName) 
       senderName, received -- add more columns as you please
     , SUM(ts_rank_cd(precompTSVector,constantTSQuery)) 
         FILTER (WHERE precomTSVector @@ constantTSQuery)
         OVER (PARTITION BY senderName) AS score 
FROM   tableA
WHERE  received BETWEEN timeA AND timeB
ORDER  BY senderName, received DESC;

首先你需要做DISTINCT ON对:

DISTINCT ON聚合函数之后应用,这就是为什么您可以将两者结合在一个SELECT. 考虑查询中的事件序列SELECT

关于新的聚合FILTER子句(需要 Postgres 9.4):

如果要添加更多(未聚合)列,则需要将其作为窗口函数运行。

如果received可以为 NULL,您将要使用DESC NULLS LAST

根据数据分布和基数,其他查询技术可能会也可能不会更快:

于 2015-02-27T19:50:09.223 回答