WHERE date_field OPERATOR Month/Day/(Variable Year) - tsql

I am trying to pull invoices that are greater than or equal to October 1 (Variable Year) for every year's renewal season. I can hard code this every year, but I'd like to not have to do this because the SQL code is embedded in a child form of a CMS (netFORUM Enterprise) and run through another application and that's too many parts to keep up.
So, the hard code starting in 2016 would look like this:
WHERE my_date_field >= '10/01/2016'
NOTE, I would run the query with this code a few times starting October 2016 and throughout the months of 2017 before October 2017. Keep in mind that some old invoices may still be present on their account from two years back (10/1/2015), which I don't want to appear in my results.
I've pondered through a few types of method, both can't quite get it.
Thanks in advance!

WHERE my_date_field BETWEEN
CONVERT(DATETIME, CONVERT(VARCHAR, YEAR(GETDATE()) - 1) + '-10-01')
AND CONVERT(DATETIME, CONVERT(VARCHAR, YEAR(GETDATE())) + '-09-30')
or for SQL Server 2012 and later:
WHERE my_date_field BETWEEN
DATEFROMPARTS(YEAR(GETDATE()) - 1, 10, 01)
AND DATEFROMPARTS (YEAR(GETDATE()), 09, 30)
and as HABO suggested, if my_date_field includes Time, don't use BETWEEN but >= and <, like:
WHERE my_date_field >= DATEFROMPARTS(YEAR(GETDATE()) - 1, 10, 01)
AND my_date_field < DATEFROMPARTS (YEAR(GETDATE()), 10, 01)

You can split the day, month, year and then replace the year with current one.
SELECT my_date_field WHERE my_date_field >= CAST(
CAST(DAY(my_date_field) AS NVARCHAR(2)) + '/' +
CAST(MONTH(my_date_field) AS NVARCHAR(2)) + '/' +
CAST(YEAR(GETDATE())) AS DATE)
OR you can simply replace the year portion to the current one.
SELECT my_date_field WHERE my_date_field >=
REPLACE(my_date_field, YEAR(my_date_field), YEAR(GETDATE()))

Related

Creating flexible date ranges in PostgreSQL

I want to make my query more flexible with dates. I am thinking of defining variables with reference to current date. currently I am coding the exact date for the last quarter, the quarter before and the quarter one year ago.
That is the query for Q1:
select '2020_Q1' as time_frame, id, status, date, agent, country, sale
from sales
where date >= '2020-01-01' and date < '2020-03-31'
I do the same for Q4 and Q1 (2019) and union in the end. Today is April 27, let's say it is 4 months from now and it is August 27th. Now, I would want to look at Q2,Q1 and Q2(2019). I believe, I would need to work with current_date, but let me know if you think there is a more efficient way.
You can use date_trunc() to get the start of the "current quarter":
select ...
from sales
where date => date_trunc('quarter', current_date)
and date < date_trunc('quarter', current_date) + interval '3 months'

How can I pull records for a full month AFTER a specific date?

I have a list of employees and their hire dates. I need to pull revenue records for their first 3 months on the job. For example, if someone is hired on August 6 2018, I need to pull their revenue records for September, October, and November 2018.
I really just need the "where" statement to find the correct dates.
Let's call the tables: bookings, employees
columns: hired_at, booked_at
I originally thought it was first 3 months from hire date, and I used
where bookings.booked_at <= dateadd(month, 3, employees.hire_date)
Upon finding out that I need the 3 months FOLLOWING the hire date, I'm not sure how to write this.
Thanks!
You should use INTERVAL, dateadd isn't supported by PostgreSQL
<= employees.hire_date - Interval '3 months'
You can check the documentation in the following link
https://www.postgresql.org/docs/9.0/functions-datetime.html
WHERE booked_at >= date_trunc('month', hired_at + interval '1 month')
AND booked_at < date_trunc('month', hired_at + interval '3 month')
where date_trunc('month', ...) always gives you the 1st of the month.

extract in postgresql date

I have a question about extract function in PostgreSQL.
I am generating reports about last month's data.
So far no problem:
where extract (month from date) = extract(month from current_date- '1 month'::interval)
But the problem with this setup is that when the data spans more than 1 year than more months will be included.
To handle this I can add another condition for year:
and extract (year from date) = extract (year from current_date)
But this will cause a problem when generating report about December in January.
How can I generate my report about December in January without the fear that I include more months.
How about this:
WHERE date_trunc('month',date)=date_trunc('month',current_date) - interval '1 month'

SQL DateDiff Weeks - Need and alternative

The MS SQL DateDiff function counts the number of boundaries crossed when calculating the difference between two dates.
Unfortunately for me, that's not what I'm after. For instance, 1 June 2012 -> 30 June 2012 crosses 4 boundaries, but covers 5 weeks.
Is there an alternative query that I can run which will give me the number of weeks that a month intersects?
UPDATE
To try and clarify exactly what I'm after:
For any given month I need the number of weeks that intersect with that month.
Also, for the suggestion of just taking the datediff and adding one, that won't work. For instance February 2010 only intersects with 4 weeks. And the DateDiff calls returns 4, meaning that simply adding 1 would leave me the wrong number of weeks.
Beware: Proper Week calculation is generally trickier than you think!
If you use Datepart(week, aDate) you make a lot of assumptions about the concept 'week'.
Does the week start on Sunday or Monday? How do you deal with the transition between week 1 and week 5x. The actual number of weeks in a year is different depending on which week calculation rule you use (first4dayweek, weekOfJan1 etc.)
if you simply want to deal with differences you could use
DATEDIFF('s', firstDateTime, secondDateTime) > (7 * 86400 * numberOfWeeks)
if the first dateTime is at 2011-01-01 15:43:22 then the difference is 5 weeks after 2011-02-05 15:43:22
EDIT: Actually, according to this post: Wrong week number using DATEPART in SQL Server
You can now use Datepart(isoww, aDate) to get ISO 8601 week number. I knew that week was broken but not that there was now a fix. Cool!
THIS WORKS if you are using monday as the first day of the week
set language = british
select datepart(ww, #endofMonthDate) -
datepart(ww, #startofMonthDate) + 1
Datepart is language sensistive. By setting language to british you make monday the first day of the week.
This returns the correct values for feburary 2010 and june 2012! (because of monday as opposed to sunday is the first day of the week).
It also seems to return correct number of weeks for january and december (regardless of year). The isoww parameter uses monday as the first day of the week, but it causes january to sometimes start in week 52/53 and december to sometimes end in week 1 (which would make your select statement more complex)
SET DATEFIRST is important when counting weeks. To check what you have you can use select ##datefirst. ##datefirst=7 means that first day of week is sunday.
set datefirst 7
declare #FromDate datetime = '20100201'
declare #ToDate datetime = '20100228'
select datepart(week, #ToDate) - datepart(week, #FromDate) + 1
Result is 5 because Sunday 28/2 - 2010 is the first day of the fifth week.
If you want to base your week calculations on first day of week is Monday you need to do this instead.
set datefirst 1
declare #FromDate datetime = '20100201'
declare #ToDate datetime = '20100228'
select datepart(week, #ToDate) - datepart(week, #FromDate) + 1
Result is 4.

First Day of Next Year for SQL Server?

This should not be this hard. I simply need the following:
SET #DueDate = CONVERT (DATETIME, '01/01/2010')
However, I need it pragmatically so that if it were March of 2010, the date given would be '01/01/2011'.
I know it's simple, but my brain isn't coming up with it. I'm sure it's with a DateAdd and getdate().
Number of year boundaries between now and year zero less one (31 dec 1899), add back on.
SELECT DATEADD(year, DATEDIFF(year, -1, GETDATE()), 0)
Let's try a date next year to get 2011. because 1 Jan 2010 is start of next year in 2009...
SELECT DATEADD(year, DATEDIFF(year, -1, '2010-03-21'), 0)
Based on the Database Journal article: How to Calculate Different SQL Server Dates:
First Day of the Next Year
I use the year interval (yy) to display the first day of the next year.
select DATEADD(yy, DATEDIFF(yy, -1, getdate()), 0)
Incidentally, with SQL 2012 you can do DATEFROMPARTS(YEAR(#date) + 1, 1, 1). In your case, DATEFROMPARTS(YEAR(GETDATE()) + 1, 1, 1)
Hat tip to https://stackoverflow.com/a/13873750/155892
Perhaps, create a table with first of the year dates, then pick the smallest that is larger than your date.
Perhaps simply put a string together, '01/01' + (MyYear + 1)?
You could add one to the current year, then concat with Jan 01, then convert back to date:
select CONVERT(datetime, CONVERT(VARCHAR(20), YEAR(GETDATE())+1) + '.01.01')
Using some parts of the examples above you could also do this. Now this assumes your acceptable date format matches M-d-yyyy.
DATEADD(year, 1,'1-1-'+convert(varchar,DATEPART(YYYY,GetDate())))
Note: You get the current date, get the year part, create a string that converts to a date, then add one to the year.