Postgres - объединить информацию один раз и добавить несколько свойств в виде столбцов - PullRequest
0 голосов
/ 01 января 2019

У меня есть таблица с именем project и представление с именем downtime_report_overview.downtime_report_overview состоит из таблицы downtimeReport (id, startTime, stopTime, downTimeCauseId, employeeId, ...) и объединенной downtimeCause.name.

Благодаря ответу Гордена ( postgres - выберите одну конкретную строку другой таблицы и сохраните ее какстолбец ), я могу включить активное время простоя (stopTime = null) через агрегат массива и фильтровать как столбец в запрос проекта.Так как в ближайшем будущем мне может понадобиться больше свойств для downtime_report_overview (например, метаданных, таких как имя пользователя), мне было интересно, если я могу извлечь правильный downtimeReport только один раз.

В приведенном ниже примере я используюагрегация массива 3 раза, один раз id, startTime иauseName.С одной стороны, он кажется многословным, а с другой - я даже не уверен, что он выберет правильную строку downTime для всех 3 столбцов.

SELECT
    COUNT(downtime_report_overview."downtimeReportId") AS "downtimeReportsTotalCount",
    FLOOR(date_part('epoch'::text, sum(downtime_report_overview."stopTime" - downtime_report_overview."startTime")))::integer AS "downtimeReportsTotalDurationInSeconds",
    (array_agg(downtime_report_overview."downtimeReportId" ORDER BY downtime_report_overview."startTime" DESC) FILTER (WHERE downtime_report_overview."stopTime" IS null))[1] AS "activeDownTimeReportId",

(array_agg(downtime_report_overview."startTime" ORDER BY downtime_report_overview."startTime" DESC) FILTER (WHERE downtime_report_overview."stopTime" IS null))[1] AS "activeDownTimeReportStartTime",

(array_agg(downtime_report_overview."downtimeCauseName" ORDER BY downtime_report_overview."startTime" DESC) FILTER (WHERE downtime_report_overview."stopTime" IS null))[1] AS "activeDownTimeReportCauseName"
...

1 Ответ

0 голосов
/ 01 января 2019

Есть несколько способов подойти к этому.Очевидно, что вы можете написать отдельное выражение для каждого столбца.Или вы можете поиграть с манипулированием целой строкой как записью.

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

SELECT p.*, tt.*
FROM (SELECT p."projectID"
             count(t."timeTrackId") as "timeTracksTotalCount",
             floor(date_part('epoch'::text, sum(t."stopTime" - t."startTime")))::integer AS "timeTracksTotalDurationInSeconds"
      FROM project p LEFT JOIN
           time_track t
           ON t."fkProjectId" = p."projectId"
      GROUP BY p."projectID"
     ) p LEFT JOIN
     (SELECT DISTINCT ON (t."fkProjectId") tt.*
      FROM time_track tt
      WHERE t."stopTime" is null
      ORDER BY t."fkProjectId", t."startTime" desc
     ) tt
     ON tt."fkProjectId" = p."projectId";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...