T-SQL: 15분 간격으로 반올림
HH:MM 값을 가장 가까운 15분 간격으로 반올림하는 가장 좋은 방법은 무엇입니까?저는 초를 추적하지 않기 때문에 초는 상관없습니다.
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입니다.datetime
s의
현재 날짜가 0인 dateadd/datediff 변형을 사용하고 있습니다.주조 불필요:
select dateadd(minute, datediff(minute,0,GETDATE()) / 15 * 15, 0)
GETDATE()는 날짜/시간을 나타냅니다.
이는 오버플로로 인해 날짜 차이가 실패하기 전 적어도 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');
저는 이것이 오래된 게시물이라는 것을 알지만 제 답변을 공유하고 싶었습니다.이는 @hbrowser 응답을 기반으로 합니다.이것이 제가 생각해 낸 것입니다.이 시간은 15분 이내로 반올림됩니다.
SELECT DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, GETDATE()) / 15.0, 0) * 15, 0);
이 논리를 사용자 정의 함수 내부가 아닌 인라인으로 수행하면 큰 레코드 집합에서 성능이 향상됩니다.
반올림이 발생하는 방식을 변경할 수 있습니다.
ROUND
를 사용하는FLOOR
또는CAST expr AS INT
항상 반올림하거나 사용합니다.CEILING
항상 반올림합니다.
사용자의 개별 사용 사례에 따라 사용해야 할 라운딩 스타일이 결정됩니다.
다음 스크립트를 사용하여 다양한 반올림 기법에 의해 제공되는 차이를 관찰할 수 있습니다.
참고: 각 결과가 TIME(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
둥근 주물 바닥 천장 시간00:00:00 00:00:00 00:00:00 00:00:00 00:00:0000:05:00 00:00:00 00:00:00 00:00:00 00:15:0000:10:00 00:15:00 00:00:00 00:00:00 00:15:0000:15:00 00:15:00 00:15:00 00:15:00 00:15:0000:20:00 00:15:00 00:15:00 00:15:00 00:30:0000:25:00 00:30:00 00:15:00 00:15:00 00:30:0000:30:00 00:30:00 00:30:00 00:30:00 00:30:0000:35:00 00:30:00 00:30:00 00:30:00 00:45:0000:40:00 00:45:00 00:30:00 00:30:00 00:45:0000:45:00 00:45:00 00:45:00 00:45:00 00:45:0000:50:00 00:45:00 00:45:00 00:45:00 01:00:0000:55:00 01:00:00 00:45:00 00:45:00 01:00:0001:00:00 01:00:00 01:00:00 01:00:00 01:00:0001:05:00 01:00:00 01:00:00 01:00:00 01:15:00
이것은 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)
다음과 같이 날짜를 가장 가까운 분기로 반올림할 수 있습니다.
cast(floor(cast(getdate() as float(53))*24*4)/(24*4) as datetime)
오버플로를 방지하기 위해 날짜를 두 배의 프레시젼으로 주조하는 시간, 두 배의 = 플로트(53).24*4를 곱하면 하루의 쿼터 수가 됩니다.바닥()을 사용하여 가장 가까운 쿼터 배수로 반올림한 다음 24*4로 나누면 정상 시간으로 다시 변환됩니다.
Andomar의 답변을 시도해보니 30과 00에서 반올림 문제가 있었습니다. 그래서 몇 가지 수정하면 완벽하게 작동합니다.
cast(round(floor(cast(getdate() as float(53))*24*4)/(24*4),5) as smalldatetime)
여기에는 가장 가까운 것이 아니라 마지막 15분 증분이 표시됩니다. 즉, 앞으로 진행되지 않습니다. 이것은 정확히 제가 필요로 했던 것입니다.
좋아요, 가장 쉬운 방법은:
분을 60으로 나누어 10진수로 변환합니다.
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
사람에게 물고기를 주시오.
사용해 보십시오.
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))
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)
--이것이 제가 가장 좋아하는 라운드 타임 방법입니다.
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)
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'
T-SQL의 시간 반올림은 실제로 매우 문제가 많고 부정확한 경우가 많습니다.
몇 년 전에 저는 모든 시간을 코드로 반올림했습니다. T-SQL에서 수행해야 할 추가 허브-버브를 사용하여 정확하게 수행했습니다.코드에서 반올림 시간은 더 쉽고 훨씬 정확합니다.
T-SQL에 갇혀 지원 코드가 없거나 해당 코드에 액세스할 수 없는 경우 앞서 언급한 예를 따르십시오.그렇지 않으면 코드가 작업을 수행하도록 하는 것이 좋습니다.
이것은 어떠세요?(가독성을 위해 추가됨)
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
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
이것은 가장 가까운 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
전제는 당신이 원하는 증가량을 파악하는 것으로 요약됩니다. 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
DECLARE @Date DATETIME = GETDATE()
SELECT @Date
, DATEADD(ms, 900000 - DATEDIFF(ms, CAST(@Date AS DATE), @Date) % 900000, @Date)
언급URL : https://stackoverflow.com/questions/830792/t-sql-round-to-nearest-15-minute-interval
'prosource' 카테고리의 다른 글
R: c++/c#/sigma 등과 동등한 +=(+) 및 ++(+)? (0) | 2023.07.07 |
---|---|
파이어베이스 실시간 데이터베이스에서 삭제하는 방법은 무엇입니까? (0) | 2023.07.07 |
아나콘다는 파이썬과 어떤 관계입니까? (0) | 2023.07.07 |
워드프레스에서 세션 토큰을 프로그래밍 방식으로 만드는 방법은? (0) | 2023.07.02 |
ggplot2 축, 범례 등이 없는 그림 (0) | 2023.07.02 |