Sql server 2008 仅使用Case语句更改日期时间字段的时间部分

Sql server 2008 仅使用Case语句更改日期时间字段的时间部分,sql-server-2008,Sql Server 2008,我想使用case语句仅更改SQL Server 2008中datetime字段的时间段我有一个将更改时间段的查询,但我需要知道如何保持日期部分完整,以便只更改时间段。意思是如果日期时间是 2015年1月1日08:45:10.863 用我的语法,我想把它改成 2015年1月1日08:30:00.000 这是我的语法,正如我所说,它将更改时间部分,但不保留日期。如何保留日期并仅更改时间部分 Create Table #Test ( [charactername] varchar(100)

我想使用
case语句
仅更改
SQL Server 2008中
datetime
字段的时间段
我有一个将更改时间段的查询,但我需要知道如何保持日期部分完整,以便只更改时间段。意思是如果日期时间是

2015年1月1日08:45:10.863

用我的语法,我想把它改成

2015年1月1日08:30:00.000

这是我的语法,正如我所说,它将更改时间部分,但不保留日期。如何保留日期并仅更改时间部分

Create Table #Test
(
    [charactername] varchar(100)
    ,[lefttabletime] datetime
)

Insert Into #Test Values
('Bob Goblin', '01/01/2015 08:14:23.000'),
('Grab Crab', '01/01/2015 08:30:56.023'),
('Mike Knight', '01/01/2015 08:45:10.863')

Select 
[charactername]
,case when CAST([lefttabletime] As TIME) > '08:40:00.000' THEN '08:30:00.000'     
else [lefttabletime]
FROM #Test

Drop Table #Test


尝试编辑其他语法 这引发了以下错误:

Msg 241,16级,状态1,第10行 从字符串转换日期和/或时间时,转换失败

我试过这个语法

Select 
[charactername]
,case when CAST([lefttabletime] As TIME) > '08:40:00.000' 
THEN CAST(CAST(CONVERT(DATE, [lefttabletime],101) AS VARCHAR) 
+ '08:40:00.000' AS DATETIME) else [lefttabletime] end
FROM #Test

我发现,如果先将
leftabletime
拆分为日期和时间组件,然后将它们与新的时间部分重新组合,会更容易:

;WITH cte AS
    (
        SELECT  charactername,
                [date] = CAST(lefttabletime as date),
                [time] = CAST(lefttabletime as time)
        FROM    #test
    )

SELECT  charactername,
        CAST([date] as datetime)
        + CAST(CASE WHEN [time] > '08:40:00' THEN '08:30:00' ELSE [time] END as datetime)
FROM    cte

您可以将这两个语句合并在一起,但我喜欢单独的CTE所提供的简单和清晰。

我通常尝试使日期时间舍入问题符合
DATEADD
/
DATEDIFF
模式,我在这里做到了这一点:

Create Table #Test
(
    [charactername] varchar(100)
    ,[lefttabletime] datetime
)

Insert Into #Test Values
('Bob Goblin', '2015-01-01T08:14:23.000'),
('Grab Crab', '2015-01-01T08:30:56.023'),
('Mike Knight', '2015-01-01T08:45:10.863')

select charactername,
    CASE WHEN DATEDIFF(minute,'20010101',lefttabletime)%60 >= 40 THEN 
        DATEADD(minute,((DATEDIFF(minute,'20010101',lefttabletime)/30)*30),'20010101')
    ELSE lefttabletime END
from #Test

Drop Table #Test
表达式
DATEADD(minute,((DATEDIFF(minute,'20010101',lefttabletime)/30)*30),'20010101')
datetime的时间向下舍入到最接近的30分钟(
20010101
是任意日期,不需要以任何方式进行调整)

我还只是使用一个单独的
DATEDIFF
来查找所需的匹配条件。在可能的情况下,使用
datetime
数据,我尝试将其保存在
datetime
变量中,或者,在最坏的情况下,保存在
int
s中。一旦你转换成字符串,你就必须开始担心格式等问题,我通常宁愿避免

结果:

charactername
--------------------- -----------------------
Bob Goblin            2015-01-01 08:14:23.000
Grab Crab             2015-01-01 08:30:56.023
Mike Knight           2015-01-01 08:30:00.000

这里要实现的完整逻辑是什么?这仅仅是“最后三分之一小时内的任何时间都应替换为
30
minutes”,还是这里还包括其他条件?