仅使用Case语句更改DateTime字段的时间部分

时间:2015-10-20 13:08:33

标签: sql-server-2008

我想使用case statement来更改datetimeSQL Server 2008字段的时间片段我有一个会更改时间片的查询,但我需要知道如何保持日期部分完整,只改变时间片。如果日期时间是

,则表示
  

01/01/2015 08:45:10.863

用我的语法我想把它改成

  

01/01/2015 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,Level 16,State 1,Line 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

2 个答案:

答案 0 :(得分:1)

如果您先将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提供的简单性和清晰度。

答案 1 :(得分:1)

我通常会尝试使日期时间舍入问题符合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是一个任意日期,不需要以任何方式进行调整。)< / p>

我也只是使用单独的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