Postgres-一次汇总信息,并添加添加多个属性作为列

时间:2019-01-01 16:18:08

标签: sql postgresql

我有一个名为project的表和一个名为downtime_report_overview的视图。 downtime_report_overview由表downtimeReportid, startTime, stopTime, downTimeCauseId, employeeId, ...)和连接的downtimeCause.name组成。

多亏了Gorden的回复(postgres - select one specfic row of another table and store it as column),我能够通过数组聚合包含活动的停机时间(stopTime = null),并作为项目查询的列进行过滤。由于我可能需要在不久的将来为downtime_report_overview提供更多属性(例如,诸如用户名之类的元数据),所以我想知道是否可以将一次仅提取一次正确的downtimeReport的方法。

在下面的示例中,我使用了3次数组聚合,一次是id,startTime和causeName。一方面看起来很冗长,另一方面,我甚至不确定它是否会为所有3列选择正确的downTime行。

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 :(得分:0)

有几种方法可以解决此问题。显然,您可以为每列编写一个单独的表达式。或者,您可以尝试处理整行作为记录。

在这种情况下,也许最简单的方法是分离聚合并获得感兴趣的行。基于原始问题,代码如下:

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";