복붙노트

[SQL] T-SQL : 라운드 근처로 15 분 간격

SQL

T-SQL : 라운드 근처로 15 분 간격

가장 가까운로 15 분 간격 MM 값 : HH를 반올림하는 가장 좋은 방법은 무엇입니까? 그들은 문제가되지 않도록 내가 초를 추적하지 않습니다.

00:08:00 becomes 00:15:00 
00:07:00 becomes 00:00:00 
01:59:00 becomes 02:00:00 

등등. 이 작업을 수행하는 우아한, 비 UDF 또는 케이스 문 방법이 있습니까?

편집 : 여기에 내가 원하고자하는 위의 값을 얻기 위해 사용하고는 SQL이있다 :

CONVERT(CHAR(8), DATEADD(n, SUM(DATEDIFF(n, starttime, stoptime)), 0), 108)

STARTTIME 및 stoptime는 SQL 날짜 시간입니다.

해결법

  1. ==============================

    1.이 방법은 라운드 여기에 T-SQL에서 시간을 대답하고 있었고, 난 그것이 당신을 위해 일한다고 생각합니다.

    이 방법은 라운드 여기에 T-SQL에서 시간을 대답하고 있었고, 난 그것이 당신을 위해 일한다고 생각합니다.

    CREATE FUNCTION [dbo].[RoundTime] (@Time datetime, @RoundTo float) RETURNS datetime
    AS
    BEGIN
        DECLARE @RoundedTime smalldatetime, @Multiplier float
    
        SET @Multiplier = 24.0 / @RoundTo
    
        SET @RoundedTime= ROUND(CAST(CAST(CONVERT(varchar, @Time, 121) AS datetime) AS float) * @Multiplier, 0) / @Multiplier
    
        RETURN @RoundedTime
    END
    
    -- Usage    
    SELECT dbo.RoundTime('13:15', 0.5)
    
  2. ==============================

    2.내가 현재 사용 오전 DATEADD / DATEDIFF 변형이에 대한 제로 (0) 날짜. 어떤 캐스팅이 필요하지 않습니다 :

    내가 현재 사용 오전 DATEADD / DATEDIFF 변형이에 대한 제로 (0) 날짜. 어떤 캐스팅이 필요하지 않습니다 :

    select dateadd(minute, datediff(minute,0,GETDATE()) / 15 * 15, 0)
    

    GETDATE ()는 당신의 날짜가 무엇이든지이다.

    이 때문에 오버 플로우의 DATEDIFF의도 실패한 전에 적어도까지 올해 5500에 날짜를 작동합니다. 당신이 두 번째 정확성을 사용하려고하는 경우에는 위의 바로 실패합니다.

    '2009-01-01', 또는 오늘 날짜 (경고, 더 추한 SQL)와 같은 또 다른 고정 날짜를 사용하여이 문제를 해결합니다. 미래 날짜도 작동합니다. 로 오래 00:00:00의 시간 부분을 가지고 당신은 그것을 다른 날짜를 기반으로 할 수 있습니다.

    예를 들어 : 가장 가까운 30 초 라운드 :

    select dateadd(second, round(datediff(second, '2010-01-01', GETDATE()) / 30.0, 0) * 30, '2010-01-01');
    
  3. ==============================

    3.나는 이것이 이전 게시물입니다 알고 있지만 내 대답을 공유하고 싶었다. 이 @hbrowser 응답을 기반으로. 내가 가지고 올 한 내용을 여기입니다. 이 반올림 또는 가까운 15 분 아래됩니다.

    나는 이것이 이전 게시물입니다 알고 있지만 내 대답을 공유하고 싶었다. 이 @hbrowser 응답을 기반으로. 내가 가지고 올 한 내용을 여기입니다. 이 반올림 또는 가까운 15 분 아래됩니다.

    SELECT DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, GETDATE()) / 15.0, 0) * 15, 0);
    

    귀하의 개인 사용 사례는 사용해야 할 수도 반올림의 어떤 스타일을 결정합니다.

    다음 스크립트는 다른 라운딩 기술을 제공하는 차이를 관찰 할 수 있습니다 :

    DECLARE @SequenceStart SmallDateTime = CAST(GETDATE() AS Date); 
    DECLARE @SequenceEnd SmallDateTime = DateAdd(HOUR, 2, @SequenceStart); -- Recursive CTEs should always have an upper limit
    DECLARE @SequenceIntMins INT = 5; -- increment by 5 to show the difference with rounding
    WITH TimeSequence([Time]) as
    (
        SELECT @SequenceStart as [Time]
        UNION ALL
        SELECT DateAdd(MINUTE, 5, [Time]) FROM TimeSequence 
        WHERE [Time] <= @SequenceEnd
    )
        SELECT [Time] = Cast([Time] as TIME(0))
        , Rounded = CAST(DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, [Time]) / 15.0, 0) * 15, 0) as TIME(0))
        , Casted = CAST(DATEADD(MINUTE, CAST(DATEDIFF(MINUTE, 0, [Time]) / 15.0 AS INT) * 15, 0) as TIME(0))
        , Floored = CAST(DATEADD(MINUTE, FLOOR(DATEDIFF(MINUTE, 0, [Time]) / 15.0) * 15, 0) as TIME(0))
        , Ceilinged = CAST(DATEADD(MINUTE, CEILING(DATEDIFF(MINUTE, 0, [Time]) / 15.0) * 15, 0) as TIME(0))
    FROM TimeSequence OPTION ( MaxRecursion 1000);
    -- MaxRecursion may be neccessary if you change the interval or end of the sequence
    
    Time        Rounded     Casted      Floored     Ceilinged
    00:00:00    00:00:00    00:00:00    00:00:00    00:00:00
    00:05:00    00:00:00    00:00:00    00:00:00    00:15:00
    00:10:00    00:15:00    00:00:00    00:00:00    00:15:00
    00:15:00    00:15:00    00:15:00    00:15:00    00:15:00
    00:20:00    00:15:00    00:15:00    00:15:00    00:30:00
    00:25:00    00:30:00    00:15:00    00:15:00    00:30:00
    00:30:00    00:30:00    00:30:00    00:30:00    00:30:00
    00:35:00    00:30:00    00:30:00    00:30:00    00:45:00
    00:40:00    00:45:00    00:30:00    00:30:00    00:45:00
    00:45:00    00:45:00    00:45:00    00:45:00    00:45:00
    00:50:00    00:45:00    00:45:00    00:45:00    01:00:00
    00:55:00    01:00:00    00:45:00    00:45:00    01:00:00
    01:00:00    01:00:00    01:00:00    01:00:00    01:00:00
    01:05:00    01:00:00    01:00:00    01:00:00    01:15:00
    
  4. ==============================

    4.당신은 가장 가까운 분기와 같은에 날짜를 반올림 할 수 있습니다 :

    당신은 가장 가까운 분기와 같은에 날짜를 반올림 할 수 있습니다 :

    cast(floor(cast(getdate() as float(53))*24*4)/(24*4) as datetime)
    

    이중 precesion에 날짜를 캐스팅하는 것은 오버 플로우 방지하기 위해 이중 = 플로트 (53). 24 * 4로 곱하기, 하루 분기의 수. 바닥 ()와 분기의 가장 가까운 배수로 라운드 후 24 * 4 분할 정상 시간으로 다시 변환합니다.

  5. ==============================

    5.Andomar의 답변을 시도, 30 및 00에서 반올림 문제가 있었다 - 몇 개조하면 되겠 어, 그래서이 완벽하게 작동합니다 :

    Andomar의 답변을 시도, 30 및 00에서 반올림 문제가 있었다 - 몇 개조하면 되겠 어, 그래서이 완벽하게 작동합니다 :

    cast(round(floor(cast(getdate() as float(53))*24*4)/(24*4),5) as smalldatetime)
    

    이는 지난 15 분 증가가 아닌 가까운, 즉 그것이 내가 필요 정확히 어떤 전진하지 않을 것이다 표시됩니다.

  6. ==============================

    6.가장 쉬운 방법은 좋아요 :

    가장 쉬운 방법은 좋아요 :

    (60)에 의해 나누어 진수 번호로 분을 변환합니다.

    8/60 = 0.1333333333333333
    

    곱셈에 의한 4

    0.1333333333333333 * 4   = 0.5333333333333333
    

    제품 라운드 :

    Round(0.5333333333333333,0) = 1
    

    4 라운드 수 나누기

    1/4 = 0.25 = 15 minutes
    

    당신은 곱셈이 60 분을하려는 경우

    0.25*60 = 15
    

    사람에게 물고기를 줘 ....

  7. ==============================

    7.이 시도:

    이 시도:

    Declare @Dt DateTime 
    Set @Dt = getDate()
    
    Select DateAdd(minute, 
            15 * ((60 * Datepart(hour, @Dt) + 
            Datepart(Minute, @Dt)+ 
            Case When DatePart(second, @Dt) < 30 
            Then 7 Else 8 End) / 15),
        DateAdd(day, DateDiff(day, 0, @Dt), 0))
    
  8. ==============================

    8.

    DECLARE @t time  ='00:51:00.000' 
    DECLARE @m  int = DATEPART(MI,@t)%15
    
    -- 2008
    SELECT DATEADD(mi,CASE WHEN @m >=8 THEN 15-@m ELSE -1*@m END,@t)
    
    -- 2012
    SELECT DATEADD(mi,IIF(@m >=8,15-@m,-1*@m),@t)
    
  9. ==============================

    9.--This 라운드 시간에 내가 좋아하는 방법입니다

    --This 라운드 시간에 내가 좋아하는 방법입니다

    DECLARE @Time DATETIME = GETDATE()
           ,@RoundInterval INT = 30  --in minutes, needs to be a number that can be divided evenly into 60
           ,@RoundDirection INT = 2  --0 is down to the last interval, 1 is to the nearest interval, 2 is up to the next interval
    
    SELECT  DATEADD(MINUTE,DATEDIFF(MINUTE,0,DATEADD(SECOND,30*@RoundDirection*@RoundInterval,@Time))/@RoundInterval*@RoundInterval,0)
    
  10. ==============================

    10.

    create function RoundQuarterHour
    (
        @dt datetime
    )
    returns datetime
    as
    begin
        declare @result datetime
        declare @mm int
        set @mm=datepart(minute,@dt)
        set @result = dateadd(minute,-@mm + (round(@mm/cast(15 as float),0)*15) , @dt )
    
        return @result
    end
    go
    
    
               select dbo.RoundQuarterHour('2009-may-5 20:00') , '00'
     union all select dbo.RoundQuarterHour('2009-may-5 20:01') , '01'
     union all select dbo.RoundQuarterHour('2009-may-5 20:07') , '07'
     union all select dbo.RoundQuarterHour('2009-may-5 20:08') , '08'
     union all select dbo.RoundQuarterHour('2009-may-5 20:22') , '22'
     union all select dbo.RoundQuarterHour('2009-may-5 20:23') , '23'
     union all select dbo.RoundQuarterHour('2009-may-5 20:37') , '37'
     union all select dbo.RoundQuarterHour('2009-may-5 20:38') , '38'
     union all select dbo.RoundQuarterHour('2009-may-5 20:52') , '52'
     union all select dbo.RoundQuarterHour('2009-may-5 20:53') , '53'
     union all select dbo.RoundQuarterHour('2009-may-5 20:59') , '59'
    
  11. ==============================

    11.T-SQL에서 시간 반올림은 실제로 매우 문제가 여러 번 정확하지 않습니다.

    T-SQL에서 시간 반올림은 실제로 매우 문제가 여러 번 정확하지 않습니다.

    몇 년 전, 나는 그것이 일어날 수 있도록하고 정확하게 일이 여분의 허브 - BUB 하나는 T-SQL에서 할 수있는 모든을 사용하여 대 코드로 시대의 모든 라운딩을 움직였다. 코드에서 번 째 쉽고 훨씬 더 정확합니다.

    T-SQL에있어 붙어 당신이 경우에는 지원 코드가없는, 또는 다음, 그 코드에 액세스 할 수 앞서 언급 한 예를 따르지 않습니다. 그렇지 않으면, 나는 겸손 코드가 일을시키는 것이 좋습니다.

  12. ==============================

    12.이건 어때? (가변 가독성 첨가)

    이건 어때? (가변 가독성 첨가)

    create function dbo.FloorTimeToQuarters
    (
     @dt as datetime
    )
    RETURNS datetime
    as
    
    BEGIN
    
     DECLARE @timeAsInt bigint
     SET @timeAsInt = ( cast( @dt as float ) * 96 )
     RETURN DateAdd( hour, @timeAsInt % 96, cast( @timeAsInt / 96 as datetime)  )
    
    END
    
  13. ==============================

    13.15 분 블록을 설정하려면 :

    15 분 블록을 설정하려면 :

    CREATE FUNCTION RoundQuarterHour (
        @dt DATETIME
    ) RETURNS DATETIME
    
    AS
    BEGIN
        DECLARE @date DATETIME
        SET @date = CONVERT(varchar(16),@dt,121) --Sin segundos, ni milisegundos
        RETURN DATEADD(MINUTE,(DATEPART(MINUTE,@date) % 15)*-1, @date)
    END
    
    PRINT dbo.RoundQuarterHour('2011/01/01 18:00:07')  --Jan  1 2011  6:00PM
    PRINT dbo.RoundQuarterHour('2011/01/01 18:01:07')  --Jan  1 2011  6:00PM
    PRINT dbo.RoundQuarterHour('2011/01/01 18:13:07')  --Jan  1 2011  6:00PM
    PRINT dbo.RoundQuarterHour('2011/01/01 18:14:07')  --Jan  1 2011  6:00PM
    PRINT dbo.RoundQuarterHour('2011/01/01 18:15:07')  --Jan  1 2011  6:15PM
    PRINT dbo.RoundQuarterHour('2011/01/01 18:16:07')  --Jan  1 2011  6:15PM
    
  14. ==============================

    14.이것은 가장 가까운 15 분 반올림됩니다. 당신은 당신의 선택의 간격 @ROUND을 수정할 수 있습니다.

    이것은 가장 가까운 15 분 반올림됩니다. 당신은 당신의 선택의 간격 @ROUND을 수정할 수 있습니다.

    Declare @Dt DateTime = '2016-01-01 14:38:00' 
    DECLARE @ROUND int = 15;
    SELECT
    CASE WHEN (DATEPART(MINUTE, @Dt) % @ROUND) * 60 + DATEPART(SECOND, @Dt) < (30 * @ROUND)
    THEN DATEADD(minute, datediff(minute,0, @Dt) / @ROUND * @ROUND, 0) 
    ELSE DATEADD(minute, (DATEDIFF(minute,0, @Dt) / @ROUND * @ROUND) + @ROUND, 0) 
    END
    
  15. ==============================

    15.전제 60 분 비율로 ... 다음 (나머지 전원이 절단)을 INT 값을 ... 거기에 도착하는 단위의 필요한 수를 파악하는 것이 무엇, 당신이 원하는 증가 무엇인지 파악을 분해하고 당신은 거기있다 그것은 라운드 최대 또는 가장 가까운 증가에 이르기까지 간단한 함수.

    전제 60 분 비율로 ... 다음 (나머지 전원이 절단)을 INT 값을 ... 거기에 도착하는 단위의 필요한 수를 파악하는 것이 무엇, 당신이 원하는 증가 무엇인지 파악을 분해하고 당신은 거기있다 그것은 라운드 최대 또는 가장 가까운 증가에 이르기까지 간단한 함수.

    간단한 기능 :

        ALTER FUNCTION [dbo].[RoundOffDateTime]
    (
        @IncDate    DATETIME,
        @Increment  INT
    )
    RETURNS SMALLDATETIME
    AS
    BEGIN
    
        DECLARE @IncrementPercent DECIMAL(2,2) = CAST(@Increment as decimal)/60
        DECLARE @IncMinutes REAL = ROUND(CAST(DATEPART(mi,@IncDate) as decimal)/CAST(@Increment as decimal),0)
        DECLARE @MinutesNeeded INT = CAST(@IncMinutes * @Increment as INT)
    
        RETURN CAST(DATEADD(mi,@MinutesNeeded,DATEADD(ss,-DATEPART(ss,@IncDate),DATEADD(mi,-DATEPART(mi,@IncDate),@IncDate))) as smalldatetime)
    
    END
    
  16. ==============================

    16.

        DECLARE   @Date             DATETIME = GETDATE()
    
        SELECT    @Date
                , DATEADD(ms, 900000 - DATEDIFF(ms, CAST(@Date AS DATE), @Date) % 900000, @Date)
    
  17. from https://stackoverflow.com/questions/830792/t-sql-round-to-nearest-15-minute-interval by cc-by-sa and MIT license