SQL Server : date subtract - sql

I am trying to do a stored procedure where I will get all people that have there StartDate value strictly equal to today's day -7 days. So I can activate them 7 days before getting to there start date.
For example I have a user 'test1' that his StartDate ='2020-12-08 00:00:00.000'
So my query should get only this record cause his
StartDate = Today's date - 7 days.
StartDate is my record that I check
CREATE PROCEDURE ActivePersonXdaysBeforeStartDate
AS
BEGIN
SET NOCOUNT ON
SELECT *
FROM Person
WHERE Active = 0
AND DATEADD (DAY, -7, StartDate) = GETDATE()
END
But this is not working any tips on how to do that? Thank you

Presumably, you want:
select *
from person
where active = 0 and startdate < dateadd (day, -7, convert(date, getdate()))
This brings all rows that are not active and whose startdate is (strictly) less than 7 days before today (not including the time component of today).

Related

Get record from table against a specific day of current week

I want to know the SQL Server query in which I can get record from the table against the specific day (like Monday OR Tuesday) of current week, OR against the specific day from the last 7 days.
Like I want to get record for 1st day of last 7 days OR Like I want to get record for the Monday OR Tuesday from current week.
By the way I can get specific day of current week through this SQL Server query
//Query
SELECT DATEADD(DD, 0 - DATEPART(DW, GETDATE()), GETDATE()) //Get Sunday
SELECT DATEADD(DD, 1 - DATEPART(DW, GETDATE()), GETDATE()) //Get Monday
SELECT DATEADD(DD, 2 - DATEPART(DW, GETDATE()), GETDATE()) //Get Tuesday
But I want to get record from the table against these days, like so:
Select * from tbl_Sale where date = "Here the specific day's date should be called"
Sorry for the long text but I really need to explain that what I need to do, so please if anyone can do this?
Return only those records where date is in the last 7 days and then further restrict your criteria to just Mondays.
SELECT *
FROM tbl_Sale
WHERE DATEDIFF(DAY, GETDATE(), date) BETWEEN -7 AND 0
AND DATENAME(WEEKDAY, date) = 'Monday'
This would also work.
SELECT *
FROM tbl_Sale
WHERE DATEDIFF(DAY, GETDATE(), date) BETWEEN -7 AND 0
AND DATEPART(WEEKDAY, date) = 2 -- by default 2 is equivalent to Monday
You will find a lot of valuable information reading up on Date and Time Data Types and Functions (Transact-SQL). So by default, DATEPART(WEEKDAY, date) will return 1 for any Sunday, 2 for any Monday, etc. However, you can set the first of the week to be whatever day you want by setting DATEFIRST.
Here is some sample code to show the Weekday Names and Weekday Numbers for a range of dates.

How to return the correct start date value from a stored procedure in this case?

I am using below case condition to calculate a StartDate variable:
DECLARE #StartDate Date =
DATEADD(DAY, CASE WHEN DATEPART(dw, GETDATE()) = 2 THEN -10 ELSE -8 END, GETDATE())
AS you can see, if today's date is Monday then 10 days are subtracted from today's date, else 8 days are deducted. Since today (10/16/2018) is not a Monday, this would return 10/8/2018 as an output (8 days deduction). If executed on Monday (10/15) then #StartDate would return 10/5 as output.
I added a table called Holidays and it has two columns Holiday Name and Date containing three records for this year: Columbus Day: 10/8, Veteran day 11/12 and Thanksgiving 11/22.
Now the challenging part I have to do is, if the returned output of #StartDate is 10/8 (query executed today: 10/16) which is a holiday (Monday), then value of #StartDate should be changed to 10/5 (previous business day, Saturday & Sunday excluded). Also if the value of #StartDate is 10/5 (query executed on 10/15), then the value should be changed to 10/4 since 10/8 was a holiday, it won't be counted for deduction of 10 days so instead of 10/5, it should be 10/4.
So in theory it should work as: check if there are any holidays that fall between today's date and #StartDate, and if so then use prior day and adjust for Mondays accordingly based on the scenario I mentioned above.
Please note that the included statement I mentioned at the top is part of a stored procedure.
How can I make this work, can someone help? Thanks in advance.
Assuming that there are never multiple dates in a row in your holiday, this will do it in a single(ish) statement. You could easily break this into two if you prefer:
DECLARE #StartDate date
;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select #StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d
left join holiday on holiday.date=dt
EDIT: This is a complete working copy. I create a table variable to hold holidays, run the initial query, then insert the returned date as a holiday, then run the query again. If you run this in sql server you will see that the second query returns the day before the first query.
declare #holiday table(date date)
DECLARE #StartDate date
;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select #StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d
left join #holiday holiday on holiday.date=dt
select #startdate
insert #holiday values (#startdate)
;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select #StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d
left join #holiday holiday on holiday.date=dt
select #startdate

Anything that expected within the last 10 days back should be received if not ignore them in SQL

I need to ignore data anything that expected within the last 10 days back should be received if not ignore it. I am not sure how to write this in SQL. I have EXPDATE column. I am not sure my statement correct or not.
I believe the logic should be like this
Expected Date + 10 Days < Today`s date?
GETDATE() < DATEADD(DAY, +10, GETDATE()) - I found this online but where can I plug in my ExpectedDate column?
Thanks in advance!!
You can do it either way-
First add 10 days to EXPDATE and compare it with todays date like below.
select * from MyTable Where DATEADD(DAY, 10, EXPDATE) < GETDATE()
The other way, you can substract 10 days from today and compare it with EXPDATE.
select * from MyTable Where DATEADD(DAY, -10, GETDATE()) > EXPDATE
I would prefer 2nd one and would use variable to calculate 10 days back date as it's constant and then use it in where clause like below.
Declare #myDate datetime
SET #myDate = DATEADD(DAY, -10, GETDATE())
select * from MyTable Where #myDate > EXPDATE

How to pull previous day's records for weekdays only?

I have this simple query that returns previous day's data.
SELECT * FROM mytable
WHERE DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),GETDATE()) = 1
Using this query becomes an issue on Mondays since the previous day is Sunday but there is no data on Sunday.
So I would like the query to retrieve Friday's data (last activity) on Monday
Any ideas how to do this?
Just a little note about date data type. The date field is of VARCHAR data type.
I inherited the database and has been in use now for over 10 years.
Thanks in advance for your assistance.
How about this?
SELECT TOP 1 WITH TIES t.*
FROM mytable t
WHERE mydate < CAST(getdate() as DATE) -- assume mydate is a date
ORDER BY CAST(mydate as DATE) DESC;
This will get the most recent day's data in the table, for any day where there is data.
EDIT:
Apparently, mydate is stored in a varchar. This is a bad idea, but if you are going to do it, then format 121 is a very good choice. I would modify the above as:
SELECT TOP 1 WITH TIES t.*
FROM mytable t
WHERE mydate < CONVERT(VARCHAR(10), getdate(), 121)
ORDER BY LEFT(mydate, 10) DESC;
Note: this does the comparison of the dates as strings. But that is okay, because the dates are in the format YYYY-MM-DD, which is comparable. If performance is an issue, I would advise a computed column on mydate (to convert to a datetime or date) with an index on the column.
You could try something like this. It asumes sunday at the first day of the week.
SELECT * FROM mytable
WHERE DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),GETDATE()) = case datepart(dw, GETDATE())
when 2 then 3 --read 3 days back on a monday
when 1 then 2 --read 2 days back on a sunday
else 1 end
Declare a datetime variable, and, with DATEPART(), determine which day of the week GETDATE() is (which day the query is being run). Then, on Mondays, change our date by negative two days.
declare #queryDate datetime;
set #queryDate = case when DATEPART(dw, GETDATE()) = 1 then DATEADD(d, -2, GETDATE()) else GETDATE() end;
select * from mytable
where DATEDIFF(day,CONVERT(datetime,mytable.mydate, 121),#queryDate) = 1

SQL getdate issue with month

i need help on my little problem.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
WHERE Day(ServiceDate) BETWEEN '1' AND Day(getdate() -2)
AND Month(ServiceDate) =
CASE
WHEN Day(getdate()) <=2
THEN Month(getdate() -1
ELSE Month(getdate())
END
AND Year(ServiceDate) = Year(getdate())
Now the problem is the first and the second of the Month.
The query don't use the last month. It shows the actual month.
I hope its clear what i need.
if we have the 01-06-2016 and i need minus 2, so the query must give me back to the day 30-05-2016
big THX
the output for today with this query
output query
Assuming you are using sql-server, you need to use DATEADD(Day, -2, GETDATE()) for subtracting 2 days from current date.
I think I understand the logic now:
If the current day is the 1st of the month, get all the records from the start of previous month, until 2 days before it ends.
If the current day is the 2nd of the month, get all the records from the start of the previous month until one day before it ends.
If the current day is the 3rd of the month or higher, get all the records from the beginning of the current month until 2 days ago.
Since you are using the FORMAT() function that was introduced in 2012 version, you can also use the EOMONTH() function that was introduced in the same version.
This function returns the date of the end of the month of the date it receives as an argument, and also have a useful optional second argument that specifies the numbers of months to add to the date passed to the function.
Using this function will allow you to write your query without using any functions on the ServiceDate column, thus enabling the use of any indexes defined on this column.
DECLARE #Now datetime = GETDATE()
SELECT FORMAT(ServiceDate, 'dd-MM-yyy') AS ServiceDate
FROM Services
WHERE (
DAY(#Now) <= 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -2))
AND ServiceDate < DATEADD(DAY, -(DAY(#Now)-1), EOMONTH(#Now, -1))
)
OR
(
DAY(GETDATE()) > 2
AND ServiceDate >= DATEADD(DAY, 1, EOMONTH(#Now, -1))
AND ServiceDate < DATEADD(DAY, -2, #Now)
)
Compute enddate as 2 days before getdate() and select data in interval from enddate's first of month and enddate.
SELECT FORMAT(ServiceDate, 'dd-MM-yyy") AS ServiceDate
FROM Services
CROSS APPLY (SELECT enddate = DATEADD(D,-2,getdate()) x
WHERE ServiceDate BETWEEN DATEADD(MONTH,DATEDIFF(MONTH,0,x.enddate),0) AND x.enddate