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>;
(<>
中的所有内容均用作占位符。)
我需要查询 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>;
(<>
中的所有内容均用作占位符。)