Query to fetch from 6am present day to next day 6am - sql

I have a requirement to fetch data from 6 am of current day 6 am of next day daily basis. I have to consider 6 am to 6 am as single day. I am able to fetch data from 6 am to 11:59 PM of a day if I want remaining 6 hours which comes next day should also be considered in previous day. Tried many possible ways to fetch the data, but nothing gave me solution.
SGHH.DateTime >= DATEADD(HOUR,6,CONVERT(VARCHAR(10), GETDATE(),120))
AND SGHH.DateTime <= DATEADD(HOUR,6,CONVERT(VARCHAR(10), GETDATE()+1,120))
tried this method but after 11:59 PM getdate() will bring the current data and getdate()+1 will fall to next day.
CAN ANY ONE PLEASE SHARE A SAMPLE QUERY TO FETCH DATA BETWEEN 6am-6am??

You need to Add 6 hours to Today's midnight time, you can achieve that by taking the date part only out of GETDATE():
DECLARE #TODAY DATETIME2 = DATEADD(HOUR, 6, CONVERT(DATE, GETDATE()));
SGHH.DateTime >= #TODAY
AND
SGHH.DateTime <= DATEADD(DAY, 1, #TODAY)

what you need is that the time 6 hours ago, was in the actual day that you are now using as a day, so anything before 6am with 6 whole hours deducted will fall in the previous day.
CONVERT(VARCHAR(10), GETDATE(),120) <= dateadd(hour,-6,SGHH.DateTime)
AND dateadd(hour,-6,SGHH.DateTime) < CONVERT(VARCHAR(10), dateadd(day,1,GETDATE()) ,120)

Related

Needing to get first of month in SQL Server, but from yesterday's date

I am working on a report that will send daily with the full months data minus the current day as it sends early and won't have relevant data from today.
Currently the parameter for the start as =dateadd(“m”,1,dateserial(year(Today),month(Today),0))
and the end as =DateAdd("d",-1,Today())
The problem is that this will skip the last day of each month. I want to change the start date to the first of the month from today - 1 day, but I am not sure how to do this?
I could change it to send with the current days data as well but with it sending at 8 AM the data would still be missing.
Probably least amount of code is to (1) subtract a day from today, (2) take the eomonth of the previous month, and (3) add a day.
SELECT DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, GETDATE()),-1));
I'm not sure what language you're doing dateserial stuff in but I'd personally do this inside SQL Server.
Also the best way to drive a report for any period is to say:
col >= start of the period
AND
col < start of *next* period
For example, for a report to cover all of last month (I realize that's not quite what you're doing, it's just a simpler example), I would say:
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(GETDATE(), -2));
...
WHERE date_column >= #start
AND date_column < DATEADD(MONTH, 1, #start);
This way you don't get bitten by all of the problems that can happen with various date/time types as you try to figure out what is the end of a day or month.
For month-to-date covering yesterday and not today, I would say:
DECLARE #today date = GETDATE();
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, #today),-1));
... WHERE date_column >= #start
AND date_column < #today;

DATEADD to return data in the last 3 months but I want full month of data

So my query aims to grab all data in the last 3 months, but only returns data when it is a full month.
I have tried:
WHERE Created_Date > DATEADD(MONTH, -3, GETDATE())
or
WHERE Created_Date > DATEADD(DAY, -90, GETDATE())
Both ways return the data in the last 3 months starting from current date. But the thing is, since my query wants to get aggregated data, so if today is 8th Aug, 3 months dating back means May has not got the full month of data (from 1st to 31st), so the aggregated data is not fully reported in the results. Does this make sense?
Is there any other way to return the full month data?
I know that we can use #startOfCurrentMonth like in here but this is 3 months we are aiming to get.
To get the days of the current month plus three full months back, simply subtract four months and get that month's last day. Then take any dates after that day.
WHERE created_date > EOMONTH(DATEADD(MONTH, -4, GETDATE()))
If created_date is a misnomer and contains datetimes instead of dates, add a day and include that:
WHERE created_date >= DATEADD(DAY, 1, EOMONTH(GETDATE(), -4)))

Find number of days in a given week according to the month for a given date. in SQL

Consider the date "2022-07-02"
For the month July first week only have 3 days in it.
I need to find the number of days in the week for the given date.
In above date the week has 3 days where "2022-07-02" day reside.
Example 2 :
For month June in 2022 first week has 5 days in the week
Therefore if i declare a date as "2022-06-03" it should pass the number of days in the week as 5
I need a query to find the number of days for the specific week.
set datefirst 1 -- assumes Monday is set as start of week
declare #myDate date = getdate();
-- calculate the next last day of week
declare #nextSunday date = dateadd(day, 7 - datepart(weekday, #myDate), #myDate);
select case
-- advancing into the next month implies a partial week
-- datediff(month, #myDate, nextSunday) = 1 would be equivalent
when day(#nextSunday) < day(#myDate) then 7 - day(#nextSunday)
-- else see if still within first week
when day(#nextSunday) < 7 then day(#nextSunday)
else 7 end;
Within a query you might use it this way:
select case
when day(nextSunday) < day(dateColumn) then 7 - day(nextSunday)
when day(nextSunday) < 7 then day(nextSunday)
else 7 end
from
myData cross apply (
values (dateadd(day, 7 - datepart(weekday, dateColumn), dateColumn))
) v(nextSunday);
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=ee5bfb52dabe31dd619cfd136689db59
If you don't want the shorthand form then just replace every instance of nextSunday in the final step with its full expression.
There's nothing in the logic that prevents this from working with another first day of week. I just chose a variable name that helped ellucidate this particular problem.

SQL Server - check if store is open

I have a table as below
StoreName | TimeOpens | DurationInMinutes | DayOfTheWeek
Dog Store '00:08:00.000' 400 1
Duck Store '00:08:00.000' 1300 1
Cat Store '00:08:00.000' 1440 1
I need to select all stores that are currently open. Times are stored in UTC so GETUTCDATE() can be used to get current time. The TimeOpens is a Time object and not a DATETIME, which is why I am a little confused how to write a query that will get me the correct answer. The scenarios are what if the time overlaps over midnight because the duration is that long as in case of Duck Store or what if the duration is 1440 minutes long meaning that its open 24 hours a day.
I thought about converting it to a DateTime first which would make things easier but then I'm not sure do I get today's date or yesterdays when calculating this. For example if I get today's date and its past midnight then I'm before the store opened which would mean its closed. I have the same problem with choosing the day of the week as if its past midnight its technically next day but it could still be open from previous day.
SELECT *
FROM Stores
WHERE GETUTCDATE() > CAST(LEFT(CONVERT(DATE, GETUTCDATE()), 10) + ' ' + LEFT(CONVERT(VARCHAR, S.[TimeOpens], 120), 12) AS DATETIME)
Edit, the query should somehow include dayoftheweek as well because each day could have a different schedule. its a 1-7 index.
You can do:
where (cast(getutcdate() as time) >= timeopens and
datediff(minute, cast(getutcdate() as time), timeopens) <= duration
) or
(cast(utcdate() as time) < dateadd(minute, duration, timeopens) and
day(dateadd(minute, duration, cast(timeopens as datetime))) > 0
)
you can use this condition to get if its still a valid opening hours.
SELECT *
FROM Stores
WHERE
datediff(mi,
dateadd(mi, DurationInMinutes,cast(concat(convert(DATE, getutcdate()), ' ', TimeOpens) as datetime))
, getutcdate()) < 0

How to count number of records present in a date range between a fixed time in SQL Server?

I need to get the number of records present in my [RecordsTable] for the last 3 months.
However the catch is I need the records which are processed between 10PM and 2AM.
For example --
07/01/2015 10PM -- 07/02/2015 2AM
07/02/2015 10PM -- 07/03/2015 2AM
07/03/2015 10PM -- 07/04/2015 2AM
The below SQL gives me the records present on any particular day starting from May,2015.
But I am not able to get the timing(10PM-2AM of next day) embedded in the SQL and need some help.
SELECT CONVERT(VARCHAR(12), RecordDate, 101),count(RecordID)
FROM [RecordsTable](NOLOCK)
WHERE RecordDate > '2015-05-01'
GROUP BY CONVERT(VARCHAR(12), RecordDate, 101)
MSSQL Supports both Date and Time datatypes. You can break up your where statement to reflect both date and time conditions separately.
SELECT COUNT(Records)
FROM TABLE
WHERE CONVERT(Date,DateCol) BETWEEN 'MM/DD/YYYY' AND 'MM/DD/YYYY'
AND CONVERT(Time,DateCol) BETWEEN 'HH:MM:SS' AND 'HH:MM:SS'
Try the following:
SELECT count(1)
FROM RecordsTable
WHERE RecordDate > '2015-05-01'
AND NOT DATEPART(hour, RecordDate) BETWEEN 2 AND 21
I assume RecordDate is a datetime or datetime2 column. between 2 and 21 will return rows where the hour for RecordDate is between 2am and 9pm, inclusive. NOT between 2 and 21 will return the reverse, giving you data for 10pm, 11pm, 12pm, and 1am. This does not include any time between 2:00am and 2:59am. If you need to include events that occurred precisely at but not after 2:00am, things get a bit tricker, but similar code based on not between would apply.
To get records in the last 3 months you can use two ways -- one by month looks like this
WHERE MONTH(colname) >= MONTH(GETDATE()) -3
This will get you inclusive months but not partial months. To get partial months is a bit more tricky because you could mean (for example for today) the 9th day of 3 months ago or you could mean 90 days ago. In the first case this works
WHERE colname >= dateadd(month,-3, getdate())
and for 90 days ago
WHERE colname >= dateadd(day,-90, getdate())
To get between 10PM and 2AM use this
WHERE datepart(hour,colname) >= 22 OR datepart(hour,colname) <= 2
Use DATEPART
SELECT COUNT(1)
FROM Table1
WHERE RecordDate > '2015-05-01'
AND (DATEPART(HOUR, RecordDate) <= 2 OR DATEPART(HOUR, RecordDate) >= 22)
Try this
SELECT count(*) FROM tablename where created_at>='2015-03-17 07:15:10' and created_at<='2015-07-09 02:23:50';
You can even use between
SELECT count(*) FROM tablename where created_at between '2015-03-17 07:15:10' and '2015-07-09 02:26:50';
You can use curdate() to get today's date