我目前有一个查询,该查询选择父资源的不同ID,同时能够过滤和排序其子表的结果。查询的基本结构如下:
SELECT s.id
FROM (
SELECT DISTINCT ON (work_items.id) work_items.id, work_item_states.id AS work_item_states_id
FROM work_items
JOIN work_item_states ON work_item_states.work_item_refer = work_items.id
WHERE work_item_states.disposition = 'cancelled'
ORDER BY work_items.id
) AS s
ORDER BY s.work_item_states_id DESC
LIMIT 50
OFFSET 0
注意:此查询中的列,过滤器,联接等仅是出于说明目的的示例。这些查询将完全不同,因为它们支持任意数据。只有查询的基本结构保持不变。
出于分页的目的,我需要能够计算子查询的总结果。现在,我只是使用一个完整的单独查询,如下所示,与上面的示例相同:
SELECT COUNT(s)
FROM (
SELECT DISTINCT ON (work_items.id) work_items.id, work_item_states.id AS work_item_states_id
FROM work_items
JOIN work_item_states ON work_item_states.work_item_refer = work_items.id
WHERE work_item_states.disposition = 'cancelled'
ORDER BY work_items.id
) AS s
这是相当低效的,因为我将使用具有数百万个条目的数据库。有谁知道我如何组合这两种查询,以便结果返回ID和子查询的计数? 像这样:
SELECT s.id, COUNT(s)
是我要寻找的,但是结果中每个ID的计数仅为1。
谢谢
答案 0 :(得分:1)
使用窗口功能可以(最简单)进行此操作。接受您的初始查询,而忽略其中的具体细节:
SELECT s.id, s.total_item_count
FROM (
SELECT DISTINCT ON (work_items.id) work_items.id
, work_item_states.id AS work_item_states_id
, count(work_items.id) over () as total_item_count
FROM work_items
JOIN work_item_states ON work_item_states.work_item_refer = work_items.id
WHERE work_item_states.disposition = 'cancelled'
ORDER BY work_items.id
) AS s
ORDER BY s.work_item_states_id DESC
LIMIT 50
OFFSET 0
请注意,在group by
或distinct on
构造之后(甚至在使用having
子句过滤之后),窗口函数也被应用在 之后。子查询返回的行数,而不是work_items
的工作表中与work_item_states
联接的行数,然后才采用不同的行或其他聚合。因此,您实际上可以在窗口函数中使用聚合函数。