【问题标题】:Aggregation in Postgres for finding last valuePostgres 中用于查找最后一个值的聚合
【发布时间】:2020-06-13 18:28:17
【问题描述】:

我在 postgres 中有一个包含聚合数据的表,这些表具有以下字段

search_term --> 一个特定的搜索词
日期 --> 执行搜索的日期
search_count --> 使用此搜索词执行了多少次搜索
min_result_count --> 搜索词返回的最小结果数是多少
max_results_count --> 搜索词返回的最大结果数是多少
last_result_count --> 上次搜索时返回的搜索结果数
zero_result_count --> 这个搜索词有多少次没有结果

其中 datesearch_term 组合是唯一的,这意味着搜索词不会在日期重复,而是会更新值。

我正在尝试编写一个为期 7 天的 sql 查询以获取以下记录
搜索词
min_result_count
最大结果计数
zero_result_count
last_result_count

我可以使用聚合 MIN、MAX、SUM 找到所有值,但我无法找到 last_result_count 的值,因为这需要我只获取最后一个值。

这是一张具有预期结果的同一张表

search_term search_count min_rc max_rc zero_count last_rc 日期 -------------------------------------------------- ------------------------------------- 学期1 10 10 20 0 4 01-01-2020 学期1 10 11 21 0 5 02-01-2020 学期1 10 12 22 0 6 03-01-2020 学期1 10 13 23 0 7 04-01-2020 学期1 10 14 24 0 8 05-01-2020 学期2 10 24 25 0 9 01-01-2020 学期2 10 23 26 0 10 02-01-2020 学期2 10 22 27 0 11 03-01-2020 学期2 10 21 28 0 12 04-01-2020 学期2 10 0 29 3 0 04-01-2020

如果我在 05-01-2020 运行查询,我应该得到

search_term search_count min_rc max_rc zero_count last_rc -------------------------------------------------- ---------------------- 期限1 50 10 24 0 8 学期2 50 0 29 3 0

如果我在 04-01-2020 运行查询,我应该得到

search_term search_count min_rc max_rc zero_count last_rc -------------------------------------------------- ---------------------- 学期1 40 10 23 0 7 学期2 40 21 28 0 12

如果我在 03-01-2020 运行查询,我应该得到

search_term search_count min_rc max_rc zero_count last_rc -------------------------------------------------- ---------------------- 学期1 30 10 23 0 6 学期2 30 22 27 0 11
  • rc 代表 result_count

等等,任何帮助推导出 last_result_count 都会很有帮助

【问题讨论】:

标签: sql postgresql window-functions


【解决方案1】:

您可以为此使用ROW_NUMBER 窗口函数。 ROW_NUMBER 用您的 int 对您的数据进行排序,然后生成一个数字。

ROW_NUMBER()OVER(PARTITION BY date,search_term ORDER BY LAST_RC) AS ROW_NUMBERED_COLUMN

然后您可以对数据进行分组并使用MAX(ROW_NUMBERED_COLUMN)

【讨论】:

  • 我们按 search_term 分组我不能在 OVER 中使用 last_rc 因为它不是 group by 的一部分
【解决方案2】:

你可以像下面这样使用window_functions

Select search_term ,
SUM(search_count) OVER (partition by search_term order BY date)  as search_count,
MIN(min_rc) OVER (partition by search_term order BY date)  as min_rc,
MAX(max_rc) OVER (partition by search_term order BY date)  as max_rc,
zero_count,
last_rc , 
DATE 
from t
ORDER BY search_term,date 

结果集:

search_term    search_count    min_rc    max_rc    zero_count    last_rc   date
term1          10              10        20         0              4       01-01-2020
term1          20              10        21         0              5       02-01-2020
term1          30              10        22         0              6       03-01-2020
term1          40              10        23         0              7       04-01-2020
term1          50              10        24         0              8       05-01-2020
term2          10              24        25         0              9       01-01-2020
term2          20              23        26         0              10      02-01-2020
term2          30              22        27         0              11      03-01-2020
term2          50              0         29         0              12      04-01-2020
term2          50              0         29         3              0       04-01-2020

更新版本*

SELECT search_term,search_count, min_rc, max_rc, zero_count, last_rc
FROM
(SELECT search_term ,
        SUM(search_count) OVER (partition by search_term order BY date) as search_count,
        MIN(min_rc) OVER (partition by search_term order BY date) as min_rc,
        MAX(max_rc) OVER (partition by search_term order BY date) as max_rc,
        zero_count,
        last_rc,
        RANK() OVER (partition by search_term order BY date desc) as rnk,
        date
 FROM t
 WHERE date <= '05-01-2020'
 ) A 
 WHERE A.rnk = 1

另一种更简单的方法,我在您发表评论后意识到您想要什么。

SELECT search_term ,
SUM(search_count) as search_count,
MIN(min_rc) as min_rc,
MAX(max_rc) as max_rc,
SUM(zero_count) as zero_count,
(SELECT last_rc FROM t as a WHERE a.search_term = t.search_term AND a.date = 
 t.date ORDER BY date desc LIMIT 1) AS last_rc,
MAX(date) as date
FROM t
WHERE date <= '05-01-2020'
GROUP BY search_term
ORDER BY search_term

使用窗口函数 last_value 更简单

Select search_term ,
SUM(search_count) as search_count,
MIN(min_rc) as min_rc,
MAX(max_rc) as max_rc,
SUM(zero_count) as zero_count,
LAST_VALUE(last_rc) OVER (Partition by search_term ORDER BY date desc) AS last_rc,
MAX(date) as date
FROM t
WHERE date <= '03-01-2020'
GROUP BY search_term
ORDER BY search_term

使用任何更新版本的结果集。

search_term search_count    min_rc  max_rc  zero_count  last_rc
term1       50              10      24      0           8
term2       50              0       29      3           0

【讨论】:

  • 如果 last_rc 不是我的 group by 子句的一部分,我如何使用它...这里我们按 search_term、search_date 分组...我不希望我的 search_term 再次出现并且再次,它应该是不同的
  • 根据您的样本数据检查我为结果集编辑的答案。
  • 这个词不能重复,因为我们要聚合7d,应该只有两条记录term1和term2,每天的结果很容易我想知道如果我们聚合一周我们应该怎么做抓住 last_rc 列中的最后一条记录并将其显示为 last_rc,请参阅我在主帖中的结果集
  • 检查更新版本。您可以使用 rank 获取 last_rc 的最新记录
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2019-03-17
  • 2021-10-23
相关资源
最近更新 更多