Insert date and time in SQL - sql

i want to generate and insert date with time to table but dont quite know how.
I need to insert date for every day to three years ahead with time
01.01.2023 07:00
01.01.2023 08:00
01.01.2023 09:00
02.01.2023 07:00
02.01.2023 08:00
02.01.2023 09:00
03.01.2023 07:00 and so on

Recursive approach:
DECLARE
#StartDate DATE,
#EndDate DATE
SELECT
#StartDate = '2023-01-01',
#EndDate = DATEADD(YEAR, 3, #StartDate);
WITH DatesCTE(RecDate) AS (
SELECT #StartDate
UNION ALL
SELECT DATEADD(DAY, 1, RecDate) FROM DatesCTE WHERE RecDate < #EndDate
)
SELECT CAST(RecDate AS VARCHAR(10)) + ' 07:00' AS dt FROM DatesCTE
UNION ALL
SELECT CAST(RecDate AS VARCHAR(10)) + ' 08:00' AS dt FROM DatesCTE
UNION ALL
SELECT CAST(RecDate AS VARCHAR(10)) + ' 09:00' AS dt FROM DatesCTE
ORDER BY dt ASC
OPTION (MAXRECURSION 0)

Related

how to convert decimal time to datetime so I can run dateadd calculation on it

I have a MSSQL table where the raw data is formatted as this:
date1 time1
2008-01-20 00:00:00 654
2008-01-20 00:00:00 659
2008-01-20 00:00:00 1759
and I need to join both of them together so I can query for example all date_time that happened in the last 15 hours. what I did was
in the select statement:
combined = CONVERT(VARCHAR(10), Date1, 103) +' ' + (left((replace((CONVERT(dec(7, 2), time1) / 100 ),'.',':')),4) + ':00') ,
This helped me with getting results for
date1 time1 combined1
2008-01-20 00:00:00 654 20/01/2008 6:54:00
2008-01-20 00:00:00 659 20/01/2008 6:59:00
2008-01-20 00:00:00 1759 20/01/2008 17:5:00
I cant change the table data & I cant get the right syntax to convert it fully (including taking in consideration the 24h hour format - 1759 for example)
And in the end I need to be able to do a where statement on the combined1 column to see only the rows that happened in the last 15 hours
DATEADD(hour, - 15, GETDATE())
Thanks in advance
Try This
select date1,time1, DATEADD(MINUTE, time1%100, DATEADD(HOUR, time1/100, convert(varchar(10),date1,101))) as Combined
from Table
Where DATEADD(MINUTE, time1%100, DATEADD(HOUR, time1/100, convert(varchar(10),date1,101)))>(DATEADD(hour,-15,GETDATE()))
Try like this:
DECLARE #date DATETIME = '2008-01-20 00:00:00'
, #Time INT = 654
SELECT DATEADD(MINUTE, #Time%100, DATEADD(HOUR, #Time/100, #date))
;WITH cte
AS (SELECT CAST('2008-01-20 00:00:00' AS DATETIME) AS date1, 654 AS Time1
UNION ALL
SELECT CAST('2008-01-20 00:00:00' AS DATETIME) AS date1, 659 AS Time1
UNION ALL
SELECT CAST('2008-01-20 00:00:00' AS DATETIME) AS date1, 1759 AS Time1
)
SELECT
DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(FORMAT(Time1, '##:##') AS TIME)), date1) AS [CombinedDateTime]
FROM cte;
--Results to:
CombinedDateTime
2008-01-20 06:54:00.000
2008-01-20 06:59:00.000
2008-01-20 17:59:00.000

SQL Query for midnight transactions

What query do I use to get transactions including midnight (past midnight). For instance:
On 1st January 2018
Our Department Stores opens daily from 7am until 2am(next day)
So 2am transactions as seen as the sale for '1 January 2018'
This is my Query
WHERE Date BETWEEN '2018-01-01' AND '2018-01-02'
and Time >= '1754-01-01 07:00:00.000' and Time <='1754-01-01 01:59:00.000'
Currently my query only takes transactions until 11:59:59
But our store opens past midnight,
I want to get transaction everyday until 2am
Ideally you should combine the Date and Time column inside a single DATETIME column. Having said that, the following should work:
WITH testdata(Date, Time) AS (
SELECT '2018-01-01', '1754-01-01 06:00:00' UNION
SELECT '2018-01-01', '1754-01-01 07:00:00' UNION
SELECT '2018-01-01', '1754-01-01 08:00:00' UNION
SELECT '2018-01-01', '1754-01-01 23:00:00' UNION
SELECT '2018-01-02', '1754-01-01 00:00:00' UNION
SELECT '2018-01-02', '1754-01-01 01:00:00' UNION
SELECT '2018-01-02', '1754-01-01 06:00:00' UNION
SELECT '2018-01-02', '1754-01-01 07:00:00' UNION
SELECT '2018-01-02', '1754-01-01 08:00:00' UNION
SELECT CAST(NULL AS DATE), CAST(NULL AS DATETIME) -- type cast
)
SELECT *
FROM testdata
WHERE Date BETWEEN '2018-01-01' AND '2018-01-02'
AND (
Date = '2018-01-01' AND Time >= '1754-01-01 07:00:00' OR
Date = '2018-01-02' AND Time < '1754-01-01 07:00:00'
)
For completeness, I am including any transaction before 7:00 AM to previous day. Result:
| Date | Time |
|------------|-------------------------|
| 2018-01-01 | 1754-01-01 07:00:00.000 |
| 2018-01-01 | 1754-01-01 08:00:00.000 |
| 2018-01-01 | 1754-01-01 23:00:00.000 |
| 2018-01-02 | 1754-01-01 00:00:00.000 |
| 2018-01-02 | 1754-01-01 01:00:00.000 |
| 2018-01-02 | 1754-01-01 06:00:00.000 |
if date column has time then just use
WHERE Date>='2018-01-01 07:00:00.000' AND Date<='2018-01-02 01:59:00.000'
As your day is offset by 2 hours into the following day, I would just pull your date back by 2 hours.
Here is some example / test code. The select subtracts 2 hours from the input #testdate datetime and then truncates it to the day, chopping off the hours
declare #testdate as datetime = '2018-01-01 10:15'
select cast(dateadd(hour,-2,#testdate) as date)
set #testdate = '2018-01-02 01:15'
select cast(dateadd(hour,-2,#testdate) as date)
Both select statements return
2018-01-01
If you store date and time separately additionally run the following sql to combine them
cast(Date as datetime) + cast(Time as datetime)
e.g
select cast(dateadd(hour,-2,cast(Date as datetime) + cast(Time as datetime)) as date)
If you just want to get transactions for the given day, you could declare the date in a variable and then have the query search for records that are between (#date + 7 hours: 7 am) and (#date + 26 hours: 2 am the next day), which you can do by using the dateadd function. For simplicity, I've declared the startdate and enddate in variables as well.
Declare #date datetime = '2018-01-01';
Declare #startdate datetime = dateadd(hour, 7, #date);
Declare #enddate datetime = dateadd(hour, 26, #date);
select *
from table
WHERE Date BETWEEN #startdate AND #enddate
This will only work if your date column is of datetime datatype, though.
If you're storing your date and time in separate columns, you can combine them. Like so:
Declare #date datetime = '2018-01-01';
Declare #startdate datetime = dateadd(hour, 7, #date);
Declare #enddate datetime = dateadd(hour, 26, #date);
select *
from table
WHERE (cast(date as datetime) + cast(cast(time as time) as datetime))
BETWEEN #startdate AND #enddate

Need to add specific time to CTE_Dates calendar

I have a Dates CTE that allows me to fill in the dates between date stamped records. (Thanks SO!) However, I need the CTE_Dates table to time stamp its "StatusDate" column with a specific time instead of '00:00:00.000' and am not quite sure how to go about ding so. Here is the CTE_Dates code:
DECLARE #StartDate date = '07/15/2017'
DECLARE #EndDate date = '07/30/2017'
;WITH cte_Dates AS
(
SELECT
CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
)
--this select statement actually pulls data from 2 CTE's that are joined but represents how I am pulling the StatusDate from CTE_Dates
select
CASE WHEN CAST(statusDate as Date) IS NULL
THEN LAG(cast(StatusDate as Date)) OVER (PARTITION BY item_no ORDER BY statStart)
ELSE StatusDate END as StatusDate,
SELECT * from cte_dates
Results:
StatusDate
2017-07-15 00:00:00.000
2017-07-16 00:00:00.000
2017-07-17 00:00:00.000
2017-07-18 00:00:00.000
2017-07-19 00:00:00.000
2017-07-20 00:00:00.000
2017-07-21 00:00:00.000
2017-07-22 00:00:00.000
2017-07-23 00:00:00.000
2017-07-24 00:00:00.000
2017-07-25 00:00:00.000
2017-07-26 00:00:00.000
2017-07-27 00:00:00.000
2017-07-28 00:00:00.000
2017-07-29 00:00:00.000
2017-07-30 00:00:00.000
The CTE works great! Except I need the timestamp to be noon...
Just add time value to date like this.
DECLARE #StartDate date = '07/15/2017'
DECLARE #EndDate date = '07/30/2017'
;WITH cte_Dates AS
(
SELECT
CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END
+ '12:00'
AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
)
SELECT * FROM CTE_Dates
You could use dateadd, adding 12 hours:
SELECT DATEADD(HOUR, 12, StatusDate) AS StatusDate FROM CTE_Dates
I would just use two CTEs:
DECLARE #StartDate date = '2017-07-15';
DECLARE #EndDate date = '2017-07-30';
DECLARE #time time = '04:00:00';
WITH cte_Dates AS (
SELECT CASE WHEN DATEPART(DAY, #StartDate) = 1 THEN #StartDate ELSE DATEADD(Day, DATEDIFF(Day, 1, #StartDate) + 1, 0) END AS StatusDate
UNION ALL
SELECT DATEADD(Day, 1,StatusDate)
FROM cte_Dates
WHERE DATEADD(Day, 1, StatusDate) <= #EndDate
),
cte_DateTimes as (
select cast(statusDate as datetime) + cast(#time as datetime)
from cte_Dates
)
SELECT *
FROM CTE_DateTimes;

Grouping incident counts into 5 minute time segments

Hoping someone can assist with how to modify the following SQL to achieve the result shown in desired output. I am not fluent in TSQL but know enough to get this far.
My objectrive is to count my incident data and group into 15 minutes time segments starting at midnight but also include zero (0) where there is no incident data in a particular time segment.
Curent Query#
;With cte As
(SELECT CONVERT (varchar(5),DATEADD(minute, 15 *
(DATEDIFF(minute, '20000101', I.CreateTimestamp) / 15), '20000101'),108)
AS CreationTime, I.IncidentShortReference AS Ref
FROM Incident I
WHERE i.CreateTimestamp between DATEADD(d,-1,GETDATE()) and GETDATE()
)
SELECT CTE.CreationTime, count(CTE.Ref) As Count
FROM cte CTE
GROUP BY CTE.CreationTime
ORDER BY CTE.CreationTime
My result
CreationTime count
00:15 2
01:00 1
01:15 1
01:30 1
01:45 2
02:00 1
02:15 1
02:30 4
(Truncated)
Desired Output
CreationTime count
00:15 2
00:30 0
00:45 0
01:00 1
01:15 1
01:30 1
01:45 2
02:00 1
02:15 1
02:30 4
02:45 0
03:00 0
(Truncated)
This uses a cte creating a record for every timestamp between midnight yesterday and now, with a count for the number of incidents in each range with sample data:
declare #incident table (CreateTimestamp datetime, IncidentShortReference varchar(5))
insert into #incident values ('4/10/2017 11:11:00', 'test')
insert into #incident values ('4/10/2017 11:12:00', 'test')
insert into #incident values ('4/10/2017 11:21:00', 'test')
insert into #incident values ('4/10/2017 11:31:00', 'test')
insert into #incident values ('4/10/2017 13:31:00', 'test')
DECLARE #dt datetime
SELECT #dt = dateadd(d, datediff(d, 0, getdate()), 0) - 1 -- yesterday at midnight
;with cte as
(
select #dt dt
union all
select DATEADD(minute, 15, dt) as Next15
FROM cte
WHERE DATEADD(minute, 15, dt) < GETDATE()
)
select convert(varchar(5), dt, 108) as CreationTime, (select count(*) FROM #incident WHERE CreateTimestamp >= dt and CreateTimestamp < dateadd(mi, 15, dt)) as count
from cte
Sample output from a random interval:
You could create a time interval CTE table like this
WITH TIME_CTE
AS(
SELECT
CAST('20170411 00:15:00' AS DATETIME) AS TimePeriod
UNION ALL
SELECT
DATEADD(MINUTE, 15, TimePeriod)
FROM TIME_CTE
WHERE
DATEADD(MINUTE, 15, TimePeriod) < CAST('20170411 23:59:00' AS DATETIME)
)
SELECT
LEFT(CONVERT(VARCHAR(10),TimePeriod,108), 5)
FROM TIME_CTE
Then join it with your original query
WITH TIME_CTE
AS(
SELECT
CAST('20170411 00:15:00' AS DATETIME) AS TimePeriod
UNION ALL
SELECT
DATEADD(MINUTE, 15, TimePeriod)
FROM TIME_CTE
WHERE
DATEADD(MINUTE, 15, TimePeriod) < CAST('20170411 23:59:00' AS DATETIME)
),
CTE
AS (
SELECT CONVERT (varchar(5),DATEADD(minute, 15 *
(DATEDIFF(minute, '20000101', I.CreateTimestamp) / 15), '20000101'),108)
AS CreationTime, I.IncidentShortReference AS Ref
FROM Incident I
WHERE i.CreateTimestamp between DATEADD(d,-1,GETDATE()) and GETDATE()
)
SELECT TIME_CTE.TimePeriod, SUM(IIF(CTE.Ref IS NULL, 0, 1)) As Count
FROM TIME_CTE
LEFT JOIN CTE ON CTE.CreationTime = TIME_CTE.TimePeriod
GROUP BY TIME_CTE.TimePeriod
ORDER BY TIME_CTE.TimePeriod

Query should be changed

I have one query this query display will be based on the day which day the hours is there based on the week it will display.
In this hours table my start date and end date starts from 2014-01-06 2014-01-12 one week..
for eg:
declare #Hours as Table ( EmpId Int, Monday Time, Tuesday Time, Wednesday Time,
Thursday Time, Friday Time, Saturday Time, Sunday Time, StartDate Date, EndDate Date );
insert into #Hours
( EmpId, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, StartDate, EndDate )
values
( 1, '08:00', '00:00', '00:00', '00:00', '00:00', '00:00', '00:00', '2014-01-06 00:00:00.000', '2014-01-12 00:00:00.000' );
select * from #Hours;
with Week as (
-- Build a table of all of the dates in the work week.
select StartDate as WorkDate, EndDate
from #Hours
union all
select DateAdd( day, 1, WorkDate ), EndDate
from Week
where WorkDate < EndDate ),
DaysHours as (
-- Build a table of the hours assigned to each date.
select EmpId,
case DatePart( weekday, W.WorkDate )
when 1 then H.Monday
when 2 then H.Tuesday
when 3 then H.Wednesday
when 4 then H.Thursday
when 5 then H.Friday
when 6 then H.Saturday
when 7 then H.Sunday
end as Hours,
WorkDate as StartDate, WorkDate as EndDate
from Week as W inner join
#Hours as H on H.StartDate <= W.WorkDate and W.WorkDate <= H.EndDate )
-- Output the non-zero hours.
select EmpId, Hours,StartDate as StartDate, EndDate
from DaysHours
where Hours <> Cast( '00:00' as Time );
need the output like this:
EmpId Hours StartDate EndDate
----------- ---------------- ---------- ----------
1 08:00:00.0000000 2014-01-06 2014-01-06
because monday only we have the value.but my output like this
EmpId Hours StartDate EndDate
----------- ---------------- ---------- ----------
1 08:00:00.0000000 2014-01-12 2014-01-12
it should work based on which day the value is there.
Can any body alter in this query itself.
Thanks,
After execution got
EmpId Hours StartDate EndDate
1 08:00:00.0000000 2014-01-06 2014-01-06
MS SQL Server 2008 R2
Try this query:
SELECT x.EmpId, ca.Hours, ca.CurrentDate AS StartDate, ca.CurrentDate AS EndDate
FROM #Hours x
CROSS APPLY
(
SELECT y.Hours, DATEADD(DAY, y.NumOfDays, x.StartDate)
FROM
(
SELECT x.Monday, 0
UNION ALL SELECT x.Tuesday, 1
UNION ALL SELECT x.Wednesday, 2
UNION ALL SELECT x.Thursday, 3
UNION ALL SELECT x.Friday, 4
UNION ALL SELECT x.Saturday, 5
UNION ALL SELECT x.Sunday, 6
) y (Hours, NumOfDays)
WHERE y.Hours <> '00:00:00.0000000'
) ca (Hours, CurrentDate);