Sql 如何在Case语句中仅显示聚合或标记的结果
我有一个获取中断时间异常的查询。我使用Case语句来标记记录。问题是,我只想列出那些被标记的或在跳过的中断或短中断列中有1的Sql 如何在Case语句中仅显示聚合或标记的结果,sql,sql-server,tsql,sql-server-2005,Sql,Sql Server,Tsql,Sql Server 2005,我有一个获取中断时间异常的查询。我使用Case语句来标记记录。问题是,我只想列出那些被标记的或在跳过的中断或短中断列中有1的 SELECT lEmployeeID, sFirstName, sLastName, SUM(TotalHours) AS TotalHours, DATEDIFF(mi, MIN(dtTimeOut), MAX(dtTimeIn)) AS BreakTime, CASE WHEN SUM(ftc.Tota
SELECT lEmployeeID, sFirstName, sLastName, SUM(TotalHours) AS TotalHours, DATEDIFF(mi, MIN(dtTimeOut), MAX(dtTimeIn)) AS BreakTime,
CASE WHEN SUM(ftc.TotalHours) > 6 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 0 THEN 1 ELSE 0 END AS SkippedBreak, CASE WHEN DATEDIFF(mi,
MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 30 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) > 0 THEN 1 ELSE 0 END AS ShortBreak
FROM dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc
WHERE (DID IS NOT NULL) OR
(DID IS NOT NULL) AND (dtTimeOut IS NULL)
GROUP BY lEmployeeID, sFirstName, sLastName, TotalHours
你需要加上
您无法在查询的WHERE部分进行筛选,因为此时尚未执行分组。分组后,可以使用HAVING子句执行其他筛选:
SELECT lEmployeeID, sFirstName, sLastName, SUM(TotalHours) AS TotalHours, DATEDIFF(mi, MIN(dtTimeOut), MAX(dtTimeIn)) AS BreakTime,
CASE WHEN SUM(ftc.TotalHours) > 6 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 0 THEN 1 ELSE 0 END AS SkippedBreak, CASE WHEN DATEDIFF(mi,
MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 30 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) > 0 THEN 1 ELSE 0 END AS ShortBreak
FROM dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc
WHERE (DID IS NOT NULL) OR
(DID IS NOT NULL) AND (dtTimeOut IS NULL)
GROUP BY lEmployeeID, sFirstName, sLastName, TotalHours
HAVING SUM(ftc.TotalHours) > 6 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 0
OR DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 30 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) > 0
或者,您可以使用子查询并筛选子查询的结果:
SELECT *
FROM (
SELECT lEmployeeID, sFirstName, sLastName, SUM(TotalHours) AS TotalHours, DATEDIFF(mi, MIN(dtTimeOut), MAX(dtTimeIn)) AS BreakTime,
CASE WHEN SUM(ftc.TotalHours) > 6 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 0 THEN 1 ELSE 0 END AS SkippedBreak, CASE WHEN DATEDIFF(mi,
MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 30 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) > 0 THEN 1 ELSE 0 END AS ShortBreak
FROM dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc
WHERE (DID IS NOT NULL) OR
(DID IS NOT NULL) AND (dtTimeOut IS NULL)
GROUP BY lEmployeeID, sFirstName, sLastName, TotalHours
) AS sub
WHERE sub.SkippedBreak = 1 OR sub.ShortBreak = 1
你想要的和你现在拥有的有什么不同?现在它列出了所有的条目。我真的只希望员工工作超过6小时,休息时间少于30分钟,或者根本没有休息……这将列出所有员工条目,即使是休息时间超过30分钟的员工。我才不在乎呢那是行不通的。不能在WHERE部分中使用聚合函数,因为它是在GROUP BY part之前计算的。错误:聚合可能不会出现在WHERE子句中,除非它出现在HAVING子句或select列表中包含的子查询中,并且被聚合的列是外部引用。这非常有帮助。我喜欢你建议子查询的方式。
SELECT *
FROM (
SELECT lEmployeeID, sFirstName, sLastName, SUM(TotalHours) AS TotalHours, DATEDIFF(mi, MIN(dtTimeOut), MAX(dtTimeIn)) AS BreakTime,
CASE WHEN SUM(ftc.TotalHours) > 6 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 0 THEN 1 ELSE 0 END AS SkippedBreak, CASE WHEN DATEDIFF(mi,
MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) < 30 AND DATEDIFF(mi, MIN(ftc.dtTimeOut), MAX(ftc.dtTimeIn)) > 0 THEN 1 ELSE 0 END AS ShortBreak
FROM dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc
WHERE (DID IS NOT NULL) OR
(DID IS NOT NULL) AND (dtTimeOut IS NULL)
GROUP BY lEmployeeID, sFirstName, sLastName, TotalHours
) AS sub
WHERE sub.SkippedBreak = 1 OR sub.ShortBreak = 1