Get Year of Previous Month (For Jan 1st) - sql

I'm currently building a YTD report in SSRS. I'm looking to edit the default "FROM" date in a calendar selection.
I'm looking to retrieve January 1st of the previous months year. For example:
(If it's Feb 16th, 2016 .. the result should be 1/1/2016
If it's Jan 10th, 2016 .. the result should be 1/1/2015)
I built this to retrieve the current year for jan 1st, but it causes issues if we're in January because I need it to retrieve the year of the previous month (in that case it would be 2015, not 2016).
Thanks!

Try this, it should work
=DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1))
UPDATE:
Based on your comment I've created this expression. It is not tested but should work.
=IIF(Today.Month>1,
DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1)),
DateAdd(DateInterval.Year,-1,DateSerial(Year(Today), Month(Today), 1))
)
Let me know if this helps.

select cast(cast(year(dateadd(mm, -1,getdate())) as varchar)+'-01-01' as date)
replace getdate() with which ever field you're basing this calculation on.
for testing:
select cast(cast(year(dateadd(mm, -1,'2015-01-22')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2016-02-01')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2015-12-12')) as varchar)+'-01-01' as date)

We want to use Date Serial which has the forma
=DateSerial(YYYY,MM,DD)
The Month is always January
The day is always the first
If the month is January, it's last year. Otherwise, it's this year.
So, assuming we have an SSRS report with a parameter called Date , we can create a new field for your January date as follows:
=iif(Month(Parameters!Date.Value)=1,
dateserial(Year(Parameters!Date.Value)-1,1,1),
dateserial(Year(Parameters!Date.Value),1,1))
if you want to do this in the query with T-SQL (version 2012) or later:
case when month(#DATE) = 1
then DATEFROMPARTS(YEAR(#DATE)-1,1,1)
else DATEFROMPARTS(YEAR(#DATE),1,1)
end
OR, in earlier versions
CASE WHEN MONTH(#DATE) = 1
THEN CAST(CAST((YEAR(#DATE)-1)*10000 + 101 AS CHAR(8)) AS DATE)
ELSE CAST(CAST((YEAR(#DATE)*10000+ 101) AS CHAR(8)) AS DATE)
END

Related

not getting previous month record using datepart in sybase

Using below depart syntax to fetch for previous month record, it is working fine till previous year,however it is giving 0 value in January month.How can we get pervious month with date part even if year is change ?
DATEPART(month(GETDATE()) -1
I understand that I used another type of DB, but I want to give a hint. I am using sql server 2019.
Firstly, you need to substitute date and only then take datepart from it.
Queries:
--dateadd -1 would subtract 1 from current month
--(Jan - 1 2022), would be December 2021
select datepart(month, dateadd(month, -1, getdate()))
--also date add covers internally the problem with 30,31 days.
--May always has 31 days, April 30. So -1 subtraction from 31th of May,would result in 30th of April.
select dateadd(month, -1, cast('2021-05-31 10:00:00' as datetime))

Last year occurrence of date and month

I am looking to find a way to find the last time the day and year combination has happened.
I have a long list of dates and I want to find out what year the date and month has last occurred.
ie. 01/01 has happened in 2018 so I want 2018 as the output.
31/12 has not happened in 2018 yet, the last time is happened was in 2017, so I want 2017 as the output.
Table 1
(01/01/2015),
(01/01/2016),
(31/12/2015),
(25/07/2004)
Return table 2
(01/01/2015, 01/01/2018),
(01/01/2016, 01/01/2018),
(31/12/2015, 31/12/2017),
(25/07/2004, 25/07/2017)
OR even just return
(01/01/2015, 2018),
(01/01/2016, 2018),
(31/12/2015, 2017),
(25/07/2004, 2017)
Is this what you want?
select t2.*,
(case when month(col) < month(current_date) or
(month(col) < month(current_date) and day(col) <= day(current_date))
then year(current_date)
else 1 + year(current_date)
end)
from table2 t2;
This is using a reasonable set of date/time functions. These can vary by database.
To filter the month and year of a given date to the current date you can use:
SELECT *
FROM YourTable
WHERE month(date) = month(get_some_date()) and year(date) = year(get_somedate())
Here you can replace get_some_date to your function logic.

SQL - check if an order date occurs after the second Saturday in July

I am querying against a table of 4 yrs of order transactions (pk = order number) and I'm looking to tag each record with particular date flags based on the order date - e.g., calendar year, calendar month, fiscal year, etc. There are date attributes that are specific to our business (e.g., not easily solved by a datepart function) that I'm having trouble with.
I was able to add "School Year" (for us that runs Aug 1 - July 31) using a case statement:
case
when datepart(month, oline.order_date_ready) between 8 and 12 then datepart(year, oline.order_date_ready)
else (datepart(year, oline.order_date_ready)-1)
end as school_yr
So for 1/19/2017, the above would return "2016", because to us the 2016 school year runs from Aug 1 2016 to July 31 2017.
But now I'm having trouble repeating the same kind of case statement for something called "Rollover Year". All of our order history tables are reset/"rolled over" on the 2nd Saturday in July every calendar year, so for example the most recent rollover date was Saturday July 9th 2016. Click to view - rollover year date ranges
My above case statement doesn't apply anymore because I can't just add "datepart(month, oline.order_date_ready) = 7" - I don't need the whole month of July, I just need all the orders occurring after the 2nd Saturday in that July. So in this example, I need everything occurring from Sat July 9 2016 to today to be flagged as rollover_date = 2016.
Is there a flexible way to do this without hard coding previous/future rollover dates into another table? That's the only way I can think to solve it currently, but I'm sure there must be a better way.
Thanks!
If you ask for the day-of-the-week of July 1st, then from there it's simple arithmetic, right? This query gives results matching your image:
SELECT y,
CONCAT(y, '-07-01')::timestamp +
CONCAT(6 - EXTRACT(DOW FROM CONCAT(y, '-07-01')::timestamp) + 7, ' days')::interval
FROM generate_series(2013, 2020) s(y)
ORDER BY y DESC
;
So given any date d from year y, if it comes before the 2nd Saturday of July, give it fiscal year y - 1. Otherwise give it fiscal year (school year?) y.

Select Date Between Just Day and Month Excluding Year

The following is the pseudo code for what I want to do:
When Date is Between 04-01 and 03-31 of the following year then output as Q1.
I know how to do this with the year but not excluding the year.
I have no idea what you mean by output "Q1". However, if you want your years to start on April 1st (which seems like a reasonable interpretation of what you are sking), the easiest way is to subtract a number of days. For most years you will deal with, you can do:
select year(dateadd(day, - (31 + 28 + 31), date) as theyear
Of course, this only works three years out of four, because of leap years. One way to fix this is with explicit logic -- but that gets messy. Another way is to add the remaining months and subtract one year:
select year(dateadd(day, (30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), date) - 1 as theyear
It's unclear exactly what you're trying to do. Q1 usually indicates a quarter, a three-month period. A quarter running from 1 April to 31 March of the following year isn't much of a quarter :)
However, assuming you're trying to select stuff within a certain span of time starting from a particular date, you might try a little date/time arithmetic. First, a few notes:
datetime values have a nominal precision of 1 millisecond (and an actual precision of approximately 3ms). That means that something like '31 March 2014 23:59:59.999' is rounded up to '1 April 2014 00:00:00.000'. The largest time value for a given day is `23:59:59.997'. This can have...deleterious effects on your queries if you're not cognizant of it. Don't ask me how I know this.
datetime literals without a time component, such as '1 April 2013', are interpreted as start-of-day ('1 April 2014 00:00:00.000').
So, something like this:
declare
#dtFrom datetime ,
#dtThru datetime
set #dtFrom = '1 April 2013'
set #dtThru = dateAdd(year,1,dtFrom)
select *
from foo t
where t.someDateTimeValue >= #dtFrom
and t.someDateTimevalue < #dtThru
should probably do you.
You might want to adjust the setting of #dtThru to suit your requirements: if you're actually looking for the end of a quarter, you migh change it to something like
set #dtThru = dateAdd(month,3,dtFrom)
If you have a fiscal year that runs from 1 April through 31 March and want to figure out, say, what fiscal year and quarter your data represents, you might do something like this:
select FiscalYear = datepart(year,t.someDateTimeValue)
- case datepart(month,t.someDateTimeValue) / 4
when 0 then 1 -- jan/feb/mar is quarter 4 of the prev FY
else 0 -- everything else is this FY
end ,
FiscalQuarter = case datepart(month,t.someDateTimevalue) / 4
when 0 then 4 -- jan/feb/mar is Q4 of the prev FY
when 1 then 1 -- apr/may/jun is Q1 of the curr FY
when 2 then 2 -- jul/aug/sep is Q2 of the curr FY
when 3 then 3 -- oct/nov/dec is Q3 of the curr FY
end ,
*
from foo t
I think what you want is the following:
SELECT year(dateadd(q, -1, mydate)) AS yearEndingQ1
FROM mytable
This would give the year as 2014 for all dates between 04/01/2014 and 03/31/2015. Of course it's possible you want a result of 2015 instead in which case you want:
SELECT year(dateadd(q, 3, mydate)) AS yearEndingQ1
FROM mytable
Hope this helps.
UPDATE per OP's comment: "I am tracking data for a year ending Quarter x. Our fiscal year is a bit weird around here. So basically it would be fiscal year ending Q1, fiscal year ending Q2, etc. Perhaps I could have provided more clarity in my question."
This would give results in three separate columns for fiscal year ending Q1, fiscal year ending Q2, and fiscal year ending Q3. (I assume you don't need anything for fiscal year ending Q4!!)
SELECT year(dateadd(q, -1, mydate)) AS yearEndingQ1
, year(dateadd(q, -2, mydate)) AS yearEndingQ2
, year(dateadd(q, -3, mydate)) AS yearEndingQ3
FROM mytable

SQL - get last month data

I have been using this query to extract information from last month
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
with the end of the year approaching, will this automatically pull Dec 2012 when i run it in Jan 2013 ?
Yes. your getdate() function will give the current date when the query is run. And you are adding -1 to the month and comparing month of date_created column and the last month. But I think you should also do comparison of year. You should add two conditions month and year both.
Yes, it will pull December data. But it will pull December data from any year, not just 2012
Yes, it will. DATEADD is a SQL internal function that adds to the full date, not just the selected part (day, month, year).