PostgreSQL数据库中有一个表,它存储了关于一本书中的单词和这些单词出现的页面的数据。大概是这样的:
headword | dict_pages | timestamp_updated
----------+------------------+------------------------
abcdefg | {229} | 2023-07-28 14:49:13+00
ccdsd | {213} | 2023-07-28 18:48:11+00
zdx | {228} | 2023-07-27 18:37:42+00
xcdferc | {227, 228} | 2023-07-27 14:47:55+00
字符串
我想知道,有多少页被处理为任何特定的一天。以下是我现在的做法:
SELECT
to_char(timestamp_updated, 'YYYY-MM-DD') as dt,
count(distinct(page_num))
FROM dictionary_word dtw, unnest(dict_pages) page_num
WHERE dict_pages IS NOT NULL
GROUP BY dt
ORDER BY dt ASC
型
我的目标是获得处理了多少新页面。以前处理过的旧页面与此统计信息无关。
从上面的例子中,使用我现有的查询,我将得到以下内容:
2023-07-27 - 2
2023-07-28 - 2
型
但是单词ccdsd
是在几天/几周/几个月前添加的,所以页面213
应该从处理页面数的计算中排除。我认为这个问题的解决方案可能是从前一天获得最大页数,2023-07-27
,也就是228
,然后对于当前一天,只计算大于228
的数字(页数)。
有什么优雅的方法可以用SQL实现这一点吗?
2条答案
按热度按时间khbbv19g1#
这个问题可以重新表述如下:
DB fiddle with step-by-step queries
1.如果使用PostgreSQL 11+:
字符串
GROUPS
窗口帮助聚合上一个和当前日期组中的所有行。文档**link_1和link_2**。
1.不太优雅的方法:
型
详情:
all_pages
将从unnest(dict_pages)
操作中获得所有页码。prev_day_max_page_stat
查询计算当前日期之前的最大页数。1.最后一个查询计算每天处理的唯一
pages_count
。它按
day_date
字段对页面进行分组,并使用筛选器筛选值where page::integer >= prev_max_page
。改进示例:
我改进了insert语句来检查查询的正确性。在下面的屏幕截图中,您可以看到,值小于前一天最大值的页面不包括在结果中。
Screenshot
| 页数| pages_count |
| --| ------------ |
| 一个| 1 |
| 二个| 2 |
| 一个| 1 |
nr7wwzry2#
下面的查询首先
unnest
是页码数组,然后在聚合过程中,过滤掉任何具有对应的dict_page
的标题词,该标题词在较早的日期被处理过(即存在一个dict_page
大于或等于所讨论的dict_page
,且时间戳较小):字符串
See fiddle