我有一个名为project
的表和一个名为downtime_report_overview
的视图。 downtime_report_overview
由表downtimeReport
(id, 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"
...
答案 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";