SQL将间隔9:32到10:02作为9:30间隔,将10:03和10:32作为10:00

时间:2019-07-04 04:24:39

标签: sql-server

我正在使用SQL,我需要获得此结果,但我不知道如何。我需要的是获取时间间隔。请参考下面的示例

     ---------------------- 
    | Time   |    Interval|
    ----------------------|
    | 9:03   |    9:00    |
    | 9:02   |    8:30    |
    | 9:32   |    9:00    |
    | 9:33   |    9:30    |
    ----------------------- 

样本间隔矩阵

    ----------------------------- 
    | Interval   |    Time       |
    -----------------------------|
    | 9:00   |    9:02 - 9:31:59 |
    | 9:30   |    9:32 - 10:01:59|
    | 10:00  |    10:02- 10:31:59|
    ----------------------- ------

所以基本上9:03 - 9:329:00的时间间隔存在,而9:33 - 10:02以9:30的间隔存在

我有这个查询

      SELECT CONVERT(time(7),DATEADD(MINUTE,(DATEPART(MINUTE, '10:32:00') / 
             30)*30,(DATEADD(HOUR, DATEDIFF(HOUR, 0, '10:32:00'), 0))))

但这是我能想到的最远的结果,结果应该是10:00间隔。您可以为我指明正确的方向,或者给我一些提示

4 个答案:

答案 0 :(得分:1)

我认为这将为您提供所需的东西:

declare @testtable table (thedate time )

insert into @testtable values ( '09:03'),   ('09:02'),    ('09:32'),    ('09:33')

select 
thedate,
case when datepart(minute,thedate) between 0 and 2  then dateadd(minute, -30,cast(cast(datepart(hour,thedate) as varchar)+':00' as time))
             when datepart(minute,thedate) between 3 and 32 then cast(cast(datepart(hour,thedate) as varchar)+':00' as time)
             else dateadd(minute, +30,cast(cast(datepart(hour,thedate) as varchar)+':00' as time))
            end
from @testtable  

产生:

09:03:00.0000000    09:00:00.0000000
09:02:00.0000000    08:30:00.0000000
09:32:00.0000000    09:00:00.0000000
09:33:00.0000000    09:30:00.0000000

答案 1 :(得分:1)

以下解决方案将DATEDIFFMINUTE相对于00:02的偏移量使用以纠正差异,然后通过将分钟作为 integers来操作,从而将时间间隔缩短为30分钟并执行/ 30 * 30,最后将结果转换回TIME

DECLARE @Times TABLE (ClockTime TIME)

INSERT INTO @Times (ClockTime)
VALUES 
    ('08:57'),
    ('08:58'),
    ('08:59'),
    ('09:00'),
    ('09:01'),
    ('09:02'),
    ('09:03'),
    ('09:05'),
    ('09:31'),
    ('09:31:59'),
    ('09:32'),
    ('10:32'),
    ('23:02'),
    ('23:03'),
    ('23:31:15')


SELECT
    T.ClockTime,
    MinutesMinus2 = DATEDIFF(MINUTE, '00:02', T.ClockTime),
    MinutesMinus2On30Intervals = DATEDIFF(MINUTE, '00:02', T.ClockTime) / 30 * 30,
    MinutesMinus2On30IntervalsAsTime = CONVERT(
        TIME, 
        DATEADD(
            MINUTE, 
            DATEDIFF(MINUTE, '00:02', T.ClockTime) / 30 * 30, -- MinutesMinus2On30Intervals
            0))
FROM
    @Times AS T

结果:

+------------------+---------------+----------------------------+----------------------------------+
|    ClockTime     | MinutesMinus2 | MinutesMinus2On30Intervals | MinutesMinus2On30IntervalsAsTime |
+------------------+---------------+----------------------------+----------------------------------+
| 08:57:00.0000000 |           535 |                        510 | 08:30:00.0000000                 |
| 08:58:00.0000000 |           536 |                        510 | 08:30:00.0000000                 |
| 08:59:00.0000000 |           537 |                        510 | 08:30:00.0000000                 |
| 09:00:00.0000000 |           538 |                        510 | 08:30:00.0000000                 |
| 09:01:00.0000000 |           539 |                        510 | 08:30:00.0000000                 |
| 09:02:00.0000000 |           540 |                        540 | 09:00:00.0000000                 |
| 09:03:00.0000000 |           541 |                        540 | 09:00:00.0000000                 |
| 09:05:00.0000000 |           543 |                        540 | 09:00:00.0000000                 |
| 09:31:00.0000000 |           569 |                        540 | 09:00:00.0000000                 |
| 09:31:59.0000000 |           569 |                        540 | 09:00:00.0000000                 |
| 09:32:00.0000000 |           570 |                        570 | 09:30:00.0000000                 |
| 10:32:00.0000000 |           630 |                        630 | 10:30:00.0000000                 |
| 23:02:00.0000000 |          1380 |                       1380 | 23:00:00.0000000                 |
| 23:03:00.0000000 |          1381 |                       1380 | 23:00:00.0000000                 |
| 23:31:15.0000000 |          1409 |                       1380 | 23:00:00.0000000                 |
+------------------+---------------+----------------------------+----------------------------------+

如果您的时间偏差发生变化,您还可以使用TIME变量来设置偏移量:

DECLARE @TimeOffset TIME = '00:02'

SELECT
    Interval = CONVERT(
        TIME, 
        DATEADD(
            MINUTE, 
            DATEDIFF(MINUTE, @TimeOffset, T.ClockTime) / 30 * 30,
            0))
FROM
    @Times AS T

答案 2 :(得分:0)

请注意,我已将interval时间范围字符串更改为开始时间和结束时间。如果数据为字符串形式,请考虑转换为2种单独的时间数据类型。否则,您将需要在查询中执行一些字符串解析

数据格式正确后,查询就是INNER JOIN

declare @sample table 
(
      [Time]        time(0)
)

insert into @sample 
values ('09:03'),   
       ('09:02'),    
       ('09:32'),     
       ('09:33')

declare @interval table
(
    [Interval]      time(0),
    [Time_Start]    time(0),
    [Time_End]      time(0)
)

insert into @interval
values  ('09:00', '09:02', '09:31:59'),
        ('09:30', '09:32', '10:01:59'),
        ('10:00', '10:02', '10:31:59')

select  s.Time, i.Interval
from    @sample s
        inner join @interval i  on  s.Time  between i.Time_Start and i.Time_End

答案 3 :(得分:0)

我将这个想法的答案提供给其他人,但我认为这更简洁易懂

DECLARE @date time = '07-04-2019 10:32:00'
SELECT CONVERT(time(7),DATEADD(MINUTE,(DATEPART(MINUTE, 
    CASE WHEN DATEPART(MINUTE, @date) = 31 THEN DATEADD(minute,-2,@date) WHEN DATEPART(MINUTE, @date) = 1 THEN DATEADD(minute,-2,@date) ELSE @date END
      ) / 30)*30,(DATEADD(HOUR, DATEDIFF(HOUR, 0, CASE WHEN DATEPART(MINUTE,@date) = 1 THEN DATEADD(HOUR,-1,@date) ELSE @date END), 0))))