Counting Calls by Half-Hour intervals - sql

I was trying to get the count of calls per half-hour interval.
Couldn't figure it out.
select
count(call_id) as '#Calls',
1/2 h(date_time) as 'Call_Interval'
from My_Table

One method to aggregate by various time intervals is with DATEADD and DATEDIFF:
SELECT
COUNT(*) as '#Calls',
DATEADD(minute, (DATEDIFF(minute, '', date_time) / 30) * 30, '') as Call_Interval
FROM dbo.My_Table
GROUP BY DATEADD(minute, (DATEDIFF(minute, '', date_time) / 30) * 30, '')
ORDER BY Call_Interval;
On a side note, the empty string constant above represents the default value for datetime. The default values for datetime and other temporal types are listed below, expressed in ISO 8601 string format:
Data Type
Default Value
date
1900-01-01
datetime
1900-01-01T00:00:00
datetime2
1900-01-01T00:00:00
datetimeoffset
1900-01-01T00:00:00+00:00
smalldatetime
1900-01-01T00:00:00
time
00:00:00
Time interval calculations with a datepart more granular than minute (i.e. second, millisecond, and microsecond) may require a more recent base datetime value than the default value (e.g. 2020-01-01T00:00:00) to avoid overflow.

Related

How to calculate exact hours between two datetime fields?

I need to calculate hours between datetime fields and I can achieve it by simply doing
select date1,date2,(date1-date2) from table; --This gives answer in DD:HH:MM:SS format
select date1,date2,(trunc(date1)-trunc(date2))*24 --This doesn't take into account the time, it only gives hours between two dates.
Is there a way I can find the difference between date times that gives the output in Hours as a number?
The 'format' comment on your first query suggests your columns are timestamps, despite the dummy column names, as the result of subtracting two timestamps is an interval. Your second query is implicitly converting both timestamps to dates before subtracting them to get an answer as a number of days - which would be fractional if you weren't truncating them and thus losing the time portion.
You can extract the number of hours from the interval difference, and also 24 * the number of days if you expect it to exceed a day:
extract(day from (date1 - date2)) * 24 + extract(hour from (date1 - date2))
If you want to include fractional hours then you can extract and manipulate the minutes and seconds too.
You can also explicitly convert to dates, and truncate or floor after manipulation:
floor((cast(date1 as date) - cast(date2 as date)) * 24)
db<>fiddle demo
Use the DATEDIFF function in sql.
Example:
SELECT DATEDIFF(HOUR, '2021-09-05 12:00:00', GETDATE());
You can find it using the differnece of dates and multiplying with 24
select date1
,date2
,(date1-date2)*24 as diff_in_hrs
from table

Converting Unix time to DateTime 103

I have a stored procedure that joins two tables of hotel booking data, however, the API that I pull my data from uses Unix time. I need to convert this to DateTime to match with my companies fields.
Currently, my conversion looks like this.
IIF([start] IS NOT NULL,
CONVERT(varchar(10), [start], 103),'') as 'ArrivalDate'
This just returns the value 1547310796 so no conversion has been done.
How do I convert the value to match 103 Date Time?
This should do it:
SELECT DATEADD(second, 1547310796 - DATEDIFF(second, GETDATE(), GETUTCDATE()), '1970-01-01')
The DATEDIFF(second, GETDATE(), GETUTCDATE()) part will give you how far behind you are from UTC time. You need to subtract that many seconds from the UTC timestamp to get the local time.
I just wanted to come back to this and add another answer in that works if you just want the date and not time.
SELECT cast(DATEADD(S,[start], '1970-01-01') as date) as 'ArrivalDate'
works on Oracle/Sql
select TO_date ('19700101000000','YYYYMMDDHH24MISS') + NUMTODSINTERVAL(<YOUR_COLUMN>+ decode (sessiontimezone, '+01:00', 3600, '+02:00', 7200, 0) , 'SECOND') as ArrivalDate

SQL Server - Check if given date+time is between two datetime variables by exact date+time

I have two datetime columns in a DB table: #Start and #End.
Both columns contain the date and time, for example:
#Start: 2018-10-01 19:00:00
#End: 2018-10-10 23:59:00
I want to know if the current date is exactly between both datetimes considering the dates and the times.
So, 2018-10-08 16:37 and 2018-10-10 23:59:00 would match this range
and 2018-10-11 00:00:00 would not.
(In this case this date is one minute later than the End date, so it is not between my datetime range).
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN Start AND End
I don't use GETDATE() in real code, I use an argument. The problem is that current date argument may contain seconds and milliseconds like 23:59:59.123. My code treats such date as not conforming given range. But I don't care about s/ms.
Is there a workaround?
Update:
The precision I want to achieve is in minutes. So I do not even need to take in account the seconds nor the milliseconds. The date time format I would be working on would be 'yyyy-MM-dd hh-mm' but I do not know how to use the BETWEEN clause converting the Start and End to the shown format so I can compare the dates.
You would seem to want this logic:
WHERE GETDATE() >= Start
AND GETDATE() < DATEADD(minute, 1, End)
Assuming that the time part of End is 23:59:00 it covers all possible values between 23:59:00 and 23:59:59.999...999.
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN '2018-10-01 19:00:00' AND '2018-10-10 23:59:00'
TRY
SELECT Id FROM Table1 WHERE
CONVERT(varchar(16),GETDATE(),121) BETWEEN
CONVERT(varchar(16),[Start], 121)
AND
CONVERT(varchar(16),[END],121);
Example of rounding without strings
DECLARE #GetDateMinutes as datetime2;
DECLARE #X as datetime2 = getdate();
--round to minutes, could be made into a function
SET #GetDateMinutes = dateadd(minute,datepart(minute,#x),dateadd(hour, datepart(hour,#x),cast(CAST(#x as date) as datetime2)))
select #x, #GetDateMinutes
Truncate the seconds using the technique described here to avoid all string conversions, then just do your comparison. Here's a fully contained example that uses cross apply and values to encapsulate the truncation logic for start and end:
-- truncate minutes from current date time
declare #currentDateTime datetime2(0) = DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), N'2018-10-01 23:58:32.912')), 0);
select #currentDateTime as CurrentDateTime
, a.*
from (values -- create a table of dummy values
(Convert(datetime2(3), N'2018-10-01 19:48:14.735'), Convert(datetime2(3), N'2018-10-10 02:00:00.000'))
, (Convert(datetime2(3), N'2018-10-01 22:43:19.532'), Convert(datetime2(3), N'2018-11-01 12:17:26.663'))
) as a (StartDateTime, EndDateTime)
cross apply (values(
-- truncate minutes from start date time
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.StartDateTime)), 0)
-- truncate minutes from end date time
, DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.EndDateTime)), 0)
)) as b (StartDateTimeWithoutSeconds, EndDateTimeWithoutSeconds)
where #currentDateTime between b.StartDateTimeWithoutSeconds and b.EndDateTimeWithoutSeconds;
Your data appears to already have the s/ms truncated from start and end but figured I'd apply the same logic to all values involved just to be consistent. Here's the formula for stripping s/ms without all the "noise" from the example:
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), <SomeDateTime>)), 0)

Get tomorrows date

I am trying to get tomorrows date in a sql statement for a date comparison but it is not working.
Below is my code:
select *
from tblcalendarentries
where convert(varchar,tblcalendarentries.[Start Time],101)
= convert(varchar, GETDATE() +1, 101)
To get tomorrows date you can use the below code that will add 1 day to the current system date:
SELECT DATEADD(day, 1, GETDATE())
GETDATE()
Returns the current database system timestamp as a datetime value without the database time zone offset. This value is derived from the operating system of the computer on which the instance of SQL Server is running.
DATEADD(datepart , number , date)
Returns a specified date with the specified number interval (signed integer) added to a specified datepart of that date.
So adding this to your code in the WHERE clause:
WHERE CONVERT(VARCHAR, tblcalendarentries.[Start Time], 101) =
CONVERT(VARCHAR, DATEADD(DAY, 1, GETDATE()), 101);
First off, GETDATE() will get you today's date in the following format:
2013-04-16 10:10:02.047
Then using DATEADD(), allows you to add (or subtract if required) a date or time interval from a specified date. So the interval could be: year, month, day, hour, minute etc.
Working with Timezones?
If you are working with systems that cross timezones, you may also want to consider using GETUTCDATE():
GETUTCDATE()
Returns the current database system timestamp as a datetime value. The database time zone offset is not included. This value represents the current UTC time (Coordinated Universal Time). This value is derived from the operating system of the computer on which the instance of SQL Server is running.
Try the below:
SELECT GETDATE() + 1
This adds one day to current date
Specify size of varchar in convert()
where convert(varchar(11),tblcalendarentries.[Start Time],101) = convert(varchar(11), GETDATE() +1, 101)
I would write:
where
DATEADD(day,DATEDIFF(day,0,tblcalendarentries.[Start Time]),0) =
DATEADD(day,DATEDIFF(day,0,GETDATE()),1)
This avoids converting dates to strings entirely, whilst also removing the time portion from both values.

SQLite - select random datetime in range

Im not familiar with SQLite. Can someone help me with generating random datetime value?
I tried to start with this (its for MS-SQL):
select dateadd(
millisecond,
cast(86400000 * RAND() as int),
convert(time, '00:00')
);
but sqlite returns error: invalid column millisecond.
I need something, that allows to generate random datetime with specified minimum and maximum date, but for now I think just need to know how to convert number to date.
Im using SQLite version 3.7.15.1.
The random() function generates random 64-bit integers.
The strftime() function with the '%s' parameter converts a date/time string into the number of seconds since 1970.
The datetime() function with the 'unixepoch' modifier converts a number of seconds into a date/time string.
To convert the random integer into the desired range of seconds, use the modulo operator (%) with the difference in seconds between the min/max dates as range, and add that to the start date.
For example, the following will generate a random timestamp in Jan 2000:
SELECT datetime(strftime('%s', '2000-01-01 00:00:00') +
abs(random() % (strftime('%s', '2000-01-31 23:59:59') -
strftime('%s', '2000-01-01 00:00:00'))
),
'unixepoch');