Выберите количество результатов подзапроса вместе с другим полем - PullRequest
0 голосов
/ 11 декабря 2018

В настоящее время у меня есть запрос, который выбирает отдельные идентификаторы родительского ресурса, и в то же время я могу фильтровать и сортировать результаты его дочерних таблиц.Основная структура запроса выглядит следующим образом:

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

Это довольно неэффективно, так как я буду работать с базами данных с миллионамизаписей.Кто-нибудь знает, как я могу объединить эти два вида запросов, чтобы результат возвращал как идентификаторы, так и количество подзапросов?Что-то вроде:

SELECT s.id, COUNT(s)

- это то, что я ищу, но это просто дает мне счет 1 для каждого идентификатора в результатах.

Спасибо

1 Ответ

0 голосов
/ 11 декабря 2018

Это возможно (и проще всего) сделать с помощью оконной функции.Принимая ваш начальный запрос и игнорируя особенности того, что находится в его середине:

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 до того, как будут взяты отдельные строки или другие агрегаты,Из-за этого вы можете использовать агрегатные функции внутри оконных функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...