Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从Datetime获取时间间隔_Sql_Sql Server_Tsql_Sql Server 2008 - Fatal编程技术网

Sql 从Datetime获取时间间隔

Sql 从Datetime获取时间间隔,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,我有一个名为Timezone的表,数据如下所示: Call_ID Start_Time 93856 2011-08-04 09:59:47.000 58796 2011-08-05 14:54:37.000 25489 2011-08-09 15:32:13.000 我希望输出为: Call_ID Start_Time Interval 93856 2011

我有一个名为Timezone的表,数据如下所示:

Call_ID        Start_Time
93856          2011-08-04 09:59:47.000
58796          2011-08-05 14:54:37.000
25489          2011-08-09 15:32:13.000
我希望输出为:

Call_ID        Start_Time                    Interval
93856          2011-08-04 09:59:47.000       0930
58796          2011-08-05 14:54:37.000       1430
25489          2011-08-09 15:32:13.000       1530
我是这样做的:

Select  Call_ID , Start_Time,
CASE WHEN DATEPART(minute,Start_Time)>30 THEN 
RIGHT('0' + CAST(DATEPART(HOUR,Start_Time) AS VARCHAR),2) + '30'          
ELSE 
RIGHT('0' + CAST(DATEPART(HOUR,Start_Time) AS VARCHAR),2) + '00'        
END
From Timezone
Group By Call_ID , Start_Time,
CASE WHEN DATEPART(minute,Start_Time)>30 THEN 
RIGHT('0' + CAST(DATEPART(HOUR,Start_Time) AS VARCHAR),2) + '30'          
ELSE 
RIGHT('0' + CAST(DATEPART(HOUR,Start_Time) AS VARCHAR),2) + '00'        
END

有更好的方法吗?

不是更短,而是更整洁,强制转换和字符串连接更少:

;WITH intervals(h) AS
(
  SELECT TOP (48) CONVERT(TIME(0), DATEADD(MINUTE, 30*(number), '00:00'))
    FROM master..spt_values
    WHERE number >= 0
    GROUP BY number
    ORDER BY number
)
SELECT
  t.Call_ID,
  t.Start_Time,
  Interval = REPLACE(CONVERT(VARCHAR(5), i.h), ':', '')
FROM intervals AS i
INNER JOIN dbo.TimeZone AS t
ON DATEDIFF(MINUTE, i.h, CONVERT(TIME(0), t.Start_Time)) BETWEEN 1 AND 30;

如果边界上有一个值,则不确定要做什么。您希望它落在当前间隔还是上一间隔?如果您想要不同的行为,可以将
在1和30之间更改为
在0和29之间更改为

+1,很像我所想的,只是您应该先除以30,然后再乘以30(在这种情况下,顺序很重要)。此外,我还考虑将
Interval
的数值作为单个值计算,类似这样:
RIGHT(10000+日期部分(小时,开始时间)*100+日期部分(小时,开始时间)/30*30,2)
,但这是个人喜好的问题。@Andriy M-谢谢,我在这里加入了一个不必要的演员阵容,加上一些括号就足够了。@Andriy M-你的版本hmmm稍微修改了
RIGHT(10000+日期部分)(小时,开始时间)*100+DATEPART(分钟,开始时间)/30*30,4)
哦,对不起,我只是忽略了该转换。(无法想象会发生什么。)我现在可以看到,您正在使用括号(带或不带转换)显式显示计算顺序。那么一切都好了,谢谢。
select Call_ID,
       Start_Time,
       right(100+datepart(hour, Start_Time), 2)+
       right(100+30*(datepart(minute, Start_Time)/30), 2) as Interval
from TimeZone