在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
子句除外,因为timeA
和timeB
每次都不同),然后我只是SELECT *
从这个视图使用timeA
子句中的特定timeB
和WHERE
。
现在考虑以下查询:
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查询的总分。
我想将此查询(可能作为子查询)合并到我的视图中,这样我也可以看到每个不同发件人的“得分”。显而易见的问题是“得分查询”取决于WHERE子句中的实际timeA
和timeB
。在查询视图本身之前,这些时间是未知的。
编辑:另一个问题是在第一个查询中也选择了someOtherColumn
(可能还有其他一些我想在视图中加入的列) - 因为正在使用聚合函数。
任何想法如何实现这一目标?或者也许欢迎一些不同的方法!
答案 0 :(得分: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 ):
如果要添加更多(未聚合的)列,则需要将其作为window function运行。
如果received
可以为NULL,则您需要使用DESC NULLS LAST
:
根据数据分布和基数,其他查询技术可能会更快或更快: