Rounding milliseconds SQL Server 2000 - sql

In Microsoft SQL Server 2000, I have this data.
1900-01-01 00:10:10.830
1900-01-01 00:10:10.430
From the above column, I want to select the datetime and round off the milliseconds, in order to get the below output
1900-01-01 00:10:11
1900-01-01 00:10:10
Thanks in advance

For SQL Server 2008 and above, you can do use DATETIME2. DATETIME2 is available in SQL Server 2008 and above - for more info see here:
SELECT CAST('1900-01-01 00:10:10.830' AS DATETIME2(0));
SELECT CAST('1900-01-01 00:10:10.430' AS DATETIME2(0));
Confirmed Output
For earlier version of SQL Sever, for example SQL Server 2000. You can do something like this:
SELECT DATEADD(ms, -DATEPART(ms, DATEADD(ms, 500, CAST('1900-01-01 00:10:10.830' AS DATETIME))) , DATEADD(ms, 500, CAST('1900-01-01 00:10:10.830' AS DATETIME)));
SELECT DATEADD(ms, -DATEPART(ms, DATEADD(ms, 500, CAST('1900-01-01 00:10:10.430' AS DATETIME))) , DATEADD(ms, 500, CAST('1900-01-01 00:10:10.430' AS DATETIME)));

SELECT *
, DateAdd(ss, rounded_second, round_down_seconds) As result
FROM (
SELECT *
, Round(nanoseconds / 1000.0, 0) As rounded_second
FROM (
SELECT the_date
, DatePart(ms, the_date) As nanoseconds
, DateAdd(ss, DateDiff(ss, 0, the_date), 0) As round_down_seconds
FROM (
SELECT '1900-01-01 00:10:10.830' As the_date
UNION ALL
SELECT '1900-01-01 00:10:10.430'
) As x
) As y
) As z
I've split out each step to be as clear as possible.
If you want a single liner:
SELECT the_date
, DateAdd(ss, Round(DatePart(ms, the_date) / 1000.0, 0), DateAdd(ss, DateDiff(ss, 0, the_date), 0)) As result
FROM (
SELECT '1900-01-01 00:10:10.830' As the_date
UNION ALL
SELECT '1900-01-01 00:10:10.430'
) As x

Related

Combining Date and Time using DATEADD and DATEDIFF

I'm trying to create a new column by combining the date and time variables. For example, the data table looks like this and "StartDateTime" is the new variable I want to create.
Date StartTime *StartDateTime*
2014-03-20 1900-01-01 10:00:00.000 2014-03-30 10:00:00.000
2015-09-23 1900-01-01 11:00:00.000 2015-09-23 11:00:00.000
I used the cast function and it seems like my current code is working.
select *,
(cast(Date as datetime) + cast(StartTime as datetime)) as StartDateTime
from my_table
But I just saw this line of code on a random website and it seems like it does the same thing. However, I didn't really get the logic behind it.
select *,
DATEADD(day, 0, DATEDIFF(day, 0, Date)) + DATEADD(day, 0 -DATEDIFF(day, 0, StartTime), StartTime) As StartDateTime
from my_table
I believe the first part DATEADD(day, 0, DATEDIFF(day, 0, Date)) just returns the original date but I don't really get the second part. My understanding is DATEDIFF(day, 0, StartTime) would just return 0 and I'm not sure why 0 -DATEDIFF(day, 0, StartTime) is necessary.
Thank you.
This is one way to combine the date and time values into a single DateTime2:
declare #Samples as Table ( StartDate Date, StartTime DateTime2 );
insert into #Samples ( StartDate, StartTime ) values
( '2014-03-20', '1900-01-01 10:00:00.000' ),
( '2015-09-23', '1900-01-01 11:00:00.000' );
select StartDate, StartTime,
-- Demonstrate how to get the time with millisecond resolution from StartTime .
Cast( StartTime as Time(3) ) as StartTimeAsTime,
-- Combine the time from StartTime with the date from StartDate .
-- Get the time, convert it to milliseconds after midnight, and add it to the date as a DateTime2 .
DateAdd( ms, DateDiff( ms, 0, Cast( StartTime as Time(3) ) ), Cast( StartDate as DateTime2 ) ) as StartDateTime
from #Samples;
I have no idea what that code is doing. And the add operator is also not supported by all datetime datatypes. The correct solution is:
select *
, dateadd(second, datepart(second, StartTime), dateadd(minute, datepart(minute, StartTime), dateadd(hour, datepart(hour, StartTime), [Date])))
from (values (convert(datetime2(0),'2014-03-20'), convert(time,'10:00:00.000'))) as X ([Date], StartTime);
Ideally you would store your StartTime value in a time datatype. But the above code will still work with a datetime2 datetype (which is the recommended form of datetime to use).

Combine Queries where one is recursive

I have a recursive query that creates a row for each hour of the previous month as follows;
WITH a AS (
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) AS [DateTime]
UNION ALL
SELECT dateadd(hour, 1, [DateTime])
FROM a
WHERE dateadd(hour, 1, [DateTime]) < EOMONTH(GETDATE(), -1)
)
SELECT
a.*
FROM a
OPTION (maxrecursion 0);
This produces these results;
DateTime
2020-11-01 00:00:00.000
2020-11-01 01:00:00.000
2020-11-01 02:00:00.000
etc.....
Next I have a query that calculates the number of calls per customer, per hour, for the previous month, as a 4 week average as follows;
SELECT
DATEADD(hour, DATEDIFF(hour, 0,
DATEADD(minute, 30 - DATEPART(minute, Timestamp + '00:30:00.000'),
Timestamp)), 0) as RoundedToHour,
Campaign,
COUNT(*)/4 AS Average
FROM [Reporting].[dbo].[New_Five9_CallLog] WITH (NOLOCK)
WHERE DATEDIFF(mm, Timestamp, GETDATE()) = 1
AND Call_Type = 'Inbound'
GROUP BY Campaign,
DATEADD(hour, DATEDIFF(hour, 0,
DATEADD(minute, 30 - DATEPART(minute, Timestamp + '00:30:00.000'),
Timestamp)), 0)
This produces the following results;
RoundedToHour Campaign Average
2020-11-01 02:00:00.000 Client1 0
2020-11-01 04:00:00.000 Client2 2
etc....
What I am having trouble doing is combining these two. My initial thoughts were to use a CTE of the recursive query as basically a where clause in my second query, but since you have to use a WITH for CTE's, and I have to use a WITH for my recursive query, that won't directly work, because you can't have nested WITH's.
My final result I am looking for is a single query that produces the 4 week average of calls for each hour of the previous month, for each client. I am open to changing how I am doing any of this if someone has a better suggestion on how to reach my ultimate goal.
You can't declare a CTE in a sub-query but you can declare multiple CTEs together. So declare both and then LEFT JOIN them.
WITH a AS (
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) AS [DateTime]
UNION ALL
SELECT dateadd(hour, 1, [DateTime])
FROM a
WHERE dateadd(hour, 1, [DateTime]) < EOMONTH(GETDATE(), -1)
), b AS (
SELECT
DATEADD(hour, DATEDIFF(hour, 0,
DATEADD(minute, 30 - DATEPART(minute, Timestamp + '00:30:00.000'),
Timestamp)), 0) as RoundedToHour,
Campaign,
COUNT(*)/4 AS Average
FROM [Reporting].[dbo].[New_Five9_CallLog] WITH (NOLOCK)
WHERE DATEDIFF(mm, Timestamp, GETDATE()) = 1
AND Call_Type = 'Inbound'
GROUP BY Campaign,
DATEADD(hour, DATEDIFF(hour, 0,
DATEADD(minute, 30 - DATEPART(minute, Timestamp + '00:30:00.000'),
Timestamp)), 0)
)
SELECT a.*, b.*
FROM a
LEFT JOIN b on b.RoundedToHour = a.DateTime
OPTION (maxrecursion 0);

Rounding time untill in SQL

I have a table with timestamp that I want to round off at 15 min. interval. I can round off using the below Query but it rounds off both 11:58 and 12:02 to 12:00 which is not what I want. I would like to round off timestamp at 15 min. interval which gives me time_untill ie for anything between 11:45 to 11:59 should be rounded off to 12 and anything between 12:00 to 12:14 should be rounded off to 12:15. Please let me know how can I achieve that? Thanks
SELECT transaction_id,
CONVERT(smalldatetime, ROUND(CONVERT(float, CONVERT(datetime, entry_date_time)) * 96.0, 0, 1) /96.0) as transaction_datetime
FROM <table>
You can use datetimefromparts():
select dateadd(minute,
15,
datetimefromparts(year(entry_date_time), month(entry_date_time), day(entry_date_time),
datepart(hour, entry_date_time),
15 * (datepart(minute, entry_date_time) / 15), 0, 0
)
) as roundup15
You could use the DATEADD/DATEDIFF method to truncate date/time values that's been available for a long time.
SELECT transaction_id,
entry_date_time,
DATEADD( MI, DATEDIFF( MI, '2010', entry_date_time)/15*15, '2010') as transaction_datetime
--FROM Sample Data
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) transaction_id,
DATEADD( SS, CHECKSUM(NEWID())%10000, CAST( GETDATE() AS smalldatetime)) AS entry_date_time
FROM sys.columns)x;
Something like this...
DECLARE #time TIME(0) = GETDATE();
SELECT
DATEADD(MINUTE,
(((DATEDIFF(MINUTE, '00:00:00', #time) % 60) / 15) * 15),
DATEADD(HOUR, DATEDIFF(HOUR, '00:00:00', #time), '00:00:00')
);

SQL SERVER : Sum of multiple datetime rows in HH:MM;SS

I'm trying to add multiple record of datetime in order to get a "Total Time".
How can I achieve that ?
2000-01-01 00:01:50.000
2000-01-01 00:02:05.000
2000-01-01 00:03:58.000
2000-01-01 00:04:54.000
Total should be : 00:12:57
SELECT DATEADD(second,
SUM(DATEDIFF(second,'20000101', YourIimes)),
'20000101')
AS TotalTime From YourTable
You can do :
select dateadd(ss, sum(datediff(ss, 0, cast(dt as time))), 0) as totaltime
from table t;
here is a test table with the data to evaluate the logic
DECLARE #Records table (Duration datetime)
INSERT INTO #Records
SELECT '2000-01-01 00:01:50.000' UNION ALL
SELECT '2000-01-01 00:02:05.000' UNION ALL
SELECT '2000-01-01 00:03:58.000' UNION ALL
SELECT '2000-01-01 00:04:54.000'
SELECT
[Total Time]=convert(varchar(10), dateadd(second, SUM(DATEDIFF(SECOND,'20000101', Duration)), 0), 108)
FROM
#Records

How to compare two dates to find time difference in SQL Server 2005, date manipulation

I have two columns:
job_start job_end
2011-11-02 12:20:37.247 2011-11-02 13:35:14.613
How would it be possible using T-SQL to find the raw amount of time that has passed between when the job started and when the job ended?
I tried this:
select (job_end - job_start) from tableA
but ended up with this:
1900-01-01 01:14:37.367
Take a look at the DateDiff() function.
-- Syntax
-- DATEDIFF ( datepart , startdate , enddate )
-- Example usage
SELECT DATEDIFF(DAY, GETDATE(), GETDATE() + 1) AS DayDiff
SELECT DATEDIFF(MINUTE, GETDATE(), GETDATE() + 1) AS MinuteDiff
SELECT DATEDIFF(SECOND, GETDATE(), GETDATE() + 1) AS SecondDiff
SELECT DATEDIFF(WEEK, GETDATE(), GETDATE() + 1) AS WeekDiff
SELECT DATEDIFF(HOUR, GETDATE(), GETDATE() + 1) AS HourDiff
...
You can see it in action / play with it here
You can use the DATEDIFF function to get the difference in minutes, seconds, days etc.
SELECT DATEDIFF(MINUTE,job_start,job_end)
MINUTE obviously returns the difference in minutes, you can also use DAY, HOUR, SECOND, YEAR (see the books online link for the full list).
If you want to get fancy you can show this differently for example 75 minutes could be displayed like this: 01:15:00:0
Here is the code to do that for both SQL Server 2005 and 2008
-- SQL Server 2005
SELECT CONVERT(VARCHAR(10),DATEADD(MINUTE,DATEDIFF(MINUTE,job_start,job_end),'2011-01-01 00:00:00.000'),114)
-- SQL Server 2008
SELECT CAST(DATEADD(MINUTE,DATEDIFF(MINUTE,job_start,job_end),'2011-01-01 00:00:00.000') AS TIME)
Cast the result as TIME and the result will be in time format for duration of the interval.
select CAST(job_end - job_start) AS TIME(0)) from tableA
I think you need the time gap between job_start & job_end.
Try this...
select SUBSTRING(CONVERT(VARCHAR(20),(job_end - job_start),120),12,8) from tableA
I ended up with this.
01:14:37
Declare the Start and End date
DECLARE #SDATE AS DATETIME
TART_DATE AS DATETIME
DECLARE #END_-- Set Start and End date
SET #START_DATE = GETDATE()
SET #END_DATE = DATEADD(SECOND, 3910, GETDATE())
-- Get the Result in HH:MI:SS:MMM(24H) format
SELECT CONVERT(VARCHAR(12), DATEADD(MS, DATEDIFF(MS, #START_DATE, #END_DATE), 0), 114) AS TimeDiff
Try this in Sql Server
SELECT
start_date as firstdate,end_date as seconddate
,cast(datediff(MI,start_date,end_date)as decimal(10,3)) as minutediff
,cast(cast(cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60) as int ) as varchar(10)) + ' ' + 'Days' + ' '
+ cast(cast((cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60) -
floor(cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60)) ) * 24 as int) as varchar(10)) + ':'
+ cast( cast(((cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60)
- floor(cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60)))*24
-
cast(floor((cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60)
- floor(cast(datediff(MI,start_date,end_date)as decimal(10,3)) / (24*60)))*24) as decimal)) * 60 as int) as varchar(10))
FROM [AdventureWorks2012].dbo.learndate
If your database StartTime = 07:00:00 and endtime = 14:00:00, and both are time type. Your query to get the time difference would be:
SELECT TIMEDIFF(Time(endtime ), Time(StartTime )) from tbl_name
If your database startDate = 2014-07-20 07:00:00 and endtime = 2014-07-20 23:00:00, you can also use this query.
Below code gives in hh:mm format.
select RIGHT(LEFT(job_end- job_start,17),5)
Take a look at DATEDIFF, this should be what you're looking for. It takes the two dates you're comparing, and the date unit you want the difference in (days, months, seconds...)
I used following logic and it worked for me like marvel:
CONVERT(TIME, DATEADD(MINUTE, DATEDIFF(MINUTE, AP.Time_IN, AP.Time_OUT), 0))
If you trying to get worked hours with some accuracy, try this (tested in SQL Server 2016)
SELECT DATEDIFF(MINUTE,job_start, job_end)/60.00;
Various DATEDIFF functionalities are:
SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
Ref: https://learn.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-2017