Sql 带有DATEADD的案例陈述,用于24小时以上的计算

Sql 带有DATEADD的案例陈述,用于24小时以上的计算,sql,case,dateadd,Sql,Case,Dateadd,我正在做一个工作项目的噩梦。我正在使用SQL从我们的排班系统中提取信息。无论出于何种原因,排班系统允许将待命轮班创建为“+0000-0700”。这是在24:00-31:00返回的 在测试SQL时,我花了好几天的时间才确定这一事实是造成我痛苦的原因。一旦例行程序达到其中一个轮班,就会出现“超出范围的错误”,这更有意义,现在我发现了问题所在 然而,由于我需要迎合代码中的古怪之处,这并不像告诉某人改变他们的做法那样简单,这样24小时的轮班就不再存在了,所以我想手动将这些问题时间解释成我可以处理的事情

我正在做一个工作项目的噩梦。我正在使用SQL从我们的排班系统中提取信息。无论出于何种原因,排班系统允许将待命轮班创建为“+0000-0700”。这是在24:00-31:00返回的

在测试SQL时,我花了好几天的时间才确定这一事实是造成我痛苦的原因。一旦例行程序达到其中一个轮班,就会出现“超出范围的错误”,这更有意义,现在我发现了问题所在

然而,由于我需要迎合代码中的古怪之处,这并不像告诉某人改变他们的做法那样简单,这样24小时的轮班就不再存在了,所以我想手动将这些问题时间解释成我可以处理的事情

以下行对我来说很有意义,但也会因超出范围错误而失败:

SELECT
    RRP.shiftdate,
    CASE 
       WHEN RDS.SHIFTSTART > ‘23:59:59’ 
          THEN DATEADD(HOUR, -24, RDS.SHIFTSTART)
          ELSE RDS.SHIFTSTART
    END AS CLEANSED_SHIFTSTART
...
但是,这会崩溃并显示此错误:

将varchar数据类型转换为日期时间数据类型导致值超出范围

功能的哪一部分在抱怨

CASE WHEN RDS.SHIFTSTART > ‘23:59:59’ THEN ‘ABOVE 24H’

这很好,但我无法解决
日期添加的问题,因为我在代码的其他地方成功地使用了它。

我试图删除此答案,但它不允许我,因为它已被接受。所以我只是我只是编辑它来说明为什么不应该使用它,以及我的错误是什么,我希望这也是有用的:

我建议使用replace,它是根据值而不是位置来工作的,所以如果我有一个时间是'28:59:28',它实际上会更改为04:59:4

我错误地提出的解决方案是:

考虑到您使用的是字符串,这应该可以做到:

SELECT CASE WHEN RDS.SHIFTSTART > '23:59:59' THEN 
                    CASE WHEN (CAST(LEFT(RDS.SHIFTSTART,2) AS INT)%24) < 10
                         THEN '0'+ REPLACE(RDS.SHIFTSTART,LEFT(RDS.SHIFTSTART,2),(CAST(LEFT(RDS.SHIFTSTART,2) AS INT)%24))
                    ELSE REPLACE(RDS.SHIFTSTART,LEFT(RDS.SHIFTSTART,2), (CAST(LEFT(RDS.SHIFTSTART,2) AS INT)%24) )
                    END
       ELSE RDS.SHIFTSTART
       END AS Cleansed_ShiftStart

这是否有助于为您指明正确的方向

我用下面的一个例子来虚构一些数据

此版本可以处理范围超过“24:00:00”的wierd“time”值以及没有前导零的“time”值(例如“7:00:00”)

这就是结果

    SHIFTSTART  my_hours_parsed my_min_sec  SHIFTSTART_profile              my_time_mod
1   157:23:00   157             :23:00      Houston, we have a problem      13:23:00
2   21:15:23    21              :15:23      Works for me                    21:15:23
3   31:50:12    31              :50:12      Houston, we have a problem      7:50:12
4   49:00:00    49              :00:00      Houston, we have a problem      1:00:00
5   7:00:00     7               :00:00      Works for me                    7:00:00
6   99:23:00    99              :23:00      Houston, we have a problem      3:23:00

希望这对您有所帮助

假设您的
shiftstart
值总是以两位数字开头,您可以将前两位数字替换为数字模24:

select stuff(rds.shiftstart, 1, 2,
             left(rds.shiftstart, 2) % 24
            ) as cleansed_shiftstart
这不会将值转换为时间;如果您希望它作为一个时间,那么转换将是安全的

我不喜欢隐式转换,我可能会明确地写:

select stuff(rds.shiftstart, 1, 2,
             try_convert(int, left(rds.shiftstart, 2)) % 24
            ) as cleansed_shiftstart

能否向架构中添加一列?您有数据库的控制权吗?谢谢,字符串仅用于显示,所以(复杂的)一些用于维护日期/时间格式的总和是不需要的。我肯定是想得太多了。谢谢你的帮助实际上,你应该使用下面的答案。我的回答错了。由于我不知道使用stuff()的选项,我还是一个初学者:)有一个我没有想到的大错误。我使用的是replace,它是根据值工作的,而不是位置,所以如果我有一个时间是'28:59:28',它实际上会更改为04:59:4。我为这个错误感到抱歉,我希望你没有因此浪费任何时间。
select stuff(rds.shiftstart, 1, 2,
             left(rds.shiftstart, 2) % 24
            ) as cleansed_shiftstart
select stuff(rds.shiftstart, 1, 2,
             try_convert(int, left(rds.shiftstart, 2)) % 24
            ) as cleansed_shiftstart