PostgreSQL 三列每个唯一日期范围的计数

PostgreSQL Three Columns With Counts Per Unique Date Ranges

我需要查询 return 每个部门每月签到的 distinct/unique 名员工 ID。

所以,我需要在一列中列出不同的员工部门 return,然后在第二列中计算本月打卡的唯一员工 ID 数量,最后打卡的员工数量第三列是一个月,然后是第四列是前一个月打卡的人数。

最终结果应该是这样的:

| DeptID | ThisMonth | LastMonth | MonthBefore |
------------------------------------------------
1001, 2, 3, 2  
1002, 4, 5, 2  
1003, 5, 7, 3  

有数以万计的时间戳,因此为了提高性能,我需要限制我带回的整体数据,然后尝试将 window 中的所有数据加起来。此外,这些结果最终将需要输入另一个临时 table.

到目前为止,我已经尝试了以下查询的变体:

SELECT
DISTINCT P.DepartmentID AS "DeptID",
--COUNT(DISTINCT CI.EmployeeID),
(SELECT COUNT(DISTINCT CI.EmployeeID) WHERE (ShiftStart >= 
(DATE_TRUNC('month',NOW())) AND ShiftEnd <= (DATE_TRUNC('month',NOW()) + '1 month'::INTERVAL - '1 day'::INTERVAL))),
(SELECT COUNT(DISTINCT CI.EmployeeID) WHERE (ShiftStart >= (DATE_TRUNC('month',NOW()) - '1 month'::INTERVAL) AND ShiftEnd <= (DATE_TRUNC('month',NOW()) - '1 day'::INTERVAL))),
(SELECT COUNT(DISTINCT CI.EmployeeID) WHERE (ShiftStart >= (DATE_TRUNC('month',NOW()) - '2 month'::INTERVAL) AND ShiftEnd <= (DATE_TRUNC('month',NOW()) - '1 month'::INTERVAL - '1 day'::INTERVAL)))
FROM TimeClock CI
INNER JOIN dbo.Personnel P ON CI.EmployeeID = P.RecordID
WHERE ShiftStart >= (DATE_TRUNC('month',NOW()) - '2 month'::INTERVAL)
AND ShiftEnd <= (DATE_TRUNC('month',NOW()) + '1 month'::INTERVAL - '1 day'::INTERVAL)
GROUP BY P.DepartmentID, CI.ShiftStart, CI.ShiftEnd--, CI.EmployeeID

我遇到的 issue/problem 是 departmentids 重复 - 很可能是因为轮班的开始和结束时间戳在 GROUP 中。如果可能的话,我不想将其分解为多个查询。

听起来条件聚合可以帮助您。老实说,我没有从查询中得到你的架构,所以我只能 post 你一个模板,这看起来一般。剩下的你就得想办法了。

SELECT <departmentid>,
       count(DISTINCT
             CASE
               WHEN <shift is this month> THEN
                 <userid>
             END),
       count(DISTINCT
             CASE
               WHEN <shift is last month> THEN
                 <userid>
             END),
       count(DISTINCT
             CASE
               WHEN <shift is from two months ago> THEN
                 <userid>
             END)
       FROM <from clause maybe with joins>
       WHERE <shifts are from now to two months ago>
       GROUP BY <departmentid>;

<> 中的所有内容均用作占位符。)