我有一个带有用户每月出勤详细信息的表,其中有一个加班列。因此,该表具有以下结构和示例数据:
Date - Id - Dept - OT - Status
12/1/2019 - 1001 - HR - 2 - P
12/2/2019 - 1001 - HR - 4 - P
12/1/2019 - 1002 - IT - 2 - P
12/2/2019 - 1002 - IT - 4 - P
我在这里省略了进出时间,因为这不是这里的主要问题。参见上文,计算了每个用户的加班时间。因此,可以很容易地按如下方式计算用户或部门的总加班详细信息:
SELECT DEPT, SUM(OT) TOTAL FROM ATTENDANCE m WHERE M.DATE >= '01-DEC-2019' AND M.DATE <= '10-DEC-2019'
GROUP BY M.DEPT
我的要求是获取具有特定日期范围的部门的每周或7天加班详细信息,加班范围为40。例如:对于一个部门,日期范围为2019年12月1日至7日,总加班时间将长达40小时或41至50小时。所以我尝试了以下方法:
SELECT DEPT, SUM(OT) TOTAL FROM ATTENDANCE m WHERE M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
HAVING SUM(OT) <= 40 GROUP BY M.DEPT
或:
SELECT DEPT, SUM(OT) TOTAL FROM ATTENDANCE m WHERE M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
HAVING SUM(OT) BETWEEN 41 AND 50 GROUP BY M.DEPT
或:
SELECT DEPT, SUM(OT) TOTAL FROM ATTENDANCE m WHERE M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
HAVING SUM(OT) > 50 GROUP BY M.DEPT
但是最后一个查询似乎返回了奇怪的输出,并且似乎返回了我在第一个查询中检索到的数据。这些是我很累的单独查询,但我在考虑是否可以使用子查询通过上述所有范围将其与CASE WHEN
配合使用:
CASE WHEN M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
AND SUM(OT) <= 40 THEN SUM(OT)
CASE WHEN M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
AND SUM(OT) BETWEEN 41 AND 50 THEN SUM(OT)
我不确定是否可以将聚集函数与CASE WHEN
语句一起使用,或者可以使用上述任何方法在查询中运行多个范围?谢谢。
您可以使用CASE
区分所有值。例如:
select
dept,
sum(ot) as total,
case when sum(ot) <= 40 then 'g1'
when sum(ot) > 40 and sum(ot) <= 50 then 'g2'
else 'g3' end as g
from attendance
where date >= '01-dec-2019' and date <= '07-dec-2019'
group by dept
您可以更明确地说明所需的输出是什么吗?您似乎正在寻找两个结果(在指定的日期范围内,加班时间为[[> 40小时的部门,以及加班时间为[[over] 40小时的部门)?]
查看您的上一个查询:CASE WHEN M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
AND SUM(OT) <= 40 THEN SUM(OT)
CASE WHEN M.DATE >= '01-DEC-2019' AND M.DATE <= '07-DEC-2019'
AND SUM(OT) BETWEEN 41 AND 50 THEN SUM(OT)
鉴于应用的日期范围是相同的,您可以将其移到WHERE
子句吗?然后,您可以使用子查询或其他方法将部门按使用了多少加班时间分组(类似这样):
SELECT
Dept
, CASE
WHEN TotalOvertime <= 40 THEN 'something'
WHEN (TotalOvertime > 40 AND <= 50) THEN 'something_else'
ELSE 'exception'
END AS OvertimeCaseStatement
FROM (
SELECT Dept
, SUM(OT) AS TotalOvertime
FROM Attendance
WHERE Date BETWEEN '01-DEC-2019' AND '07-DEC-2019'
GROUP BY Dept
)
;
我在您的int比较中也删除了BETWEEN
运算符,因为我认为使用逻辑运算符更容易理解[[bit
BETWEEN
是包含运算符),并添加了一些错误的名称,例如something
,something_else
等,您可以更改这些名称以获得更多描述性名称。请让我知道我是否正在解决您的实际问题,以及这种方法是否存在新的错误/问题!同样是FWIW,如果
Date
列是日期而不是字符串,则可能有助于CAST
您的参数('01-DEC-2019'
等)成为日期类型。希望这会有所帮助!