How to print last sunday of the year in Oracle - sql

I need to print the last sunday of the year from which adding 7 to it will give me all the sundays of next year.
I have the code to print all sundays for a particular year if i have a start date but i need the user to put the year so that last sunday of the previous year will be generated and 7 will be added to get first sunday of that year and so on till it reaches last sunday of next year
For example input year is 2017 it will check the last sunday of 2016 and add 7 to it to get first sunday of 2017 which is 1-1-2017 and it will go on printing all sundays till it reaches 31st december 2017

The function next_day() takes two arguments: a date and the name of a day of the week. It returns the closest "next" day (following the date argument) that matches the given day of the week. So the result is between one and seven days forward. (If you want 'Tuesday' and the input date is a Tuesday, the function returns the date seven days later.)
If you want the last Sunday of a year, it will be between Dec. 25 and Dec. 31. So if you call the next_day() function with the arguments Dec. 24 (!!) and 'Sunday' you'll get what you want.
The result will have the same time-of-day as the date argument, so if you give a date without a time-of-day, so will be the output (which is probably what you want). So:
select next_day(date '2016-12-24', 'Sunday') from dual;
NEXT_DAY(D
----------
2016-12-25
Added: If you take an input from your user, as a bind variable, you can do something like this:
select next_day(to_date(:input_year - 1 || '-12-24', 'yyyy-mm-dd'), 'Sunday') from dual;
If you provide 2017 as input (whatever mechanism your interface has for bind variables), the output will be 2016-12-25 (in DATE data type, so don't ask "in what format" - dates don't have a format!)

Related

Weeks rolling up to months in SQL (date_trunc)

I am working on a MODE Case Study which can be accessed here https://mode.com/sql-tutorial/a-drop-in-user-engagement/#the-problem.
I am trying to access Table 2: Events which has a date column 'occurred_at'. I wanted to check the time frame of this case study, that is weeks and months.
I wrote a simple query
select distinct(date_trunc('week', occurred_at)) as week, date_trunc('month', occurred_at) as month
from tutorial.yammer_events
where event_type = 'engagement'
order by week;
and to my surprise, the first week of '2014-04-28' showed the month 'May' instead of 'April.
Can someone please tell me what is the reason for this?
Thank you
The PostgreSQL date_trunc rolls up the date to the first instance of the date depending upon the granularity (day, week, month, etc.)
For month this instance is the first day of month i.e. Day 1.
For week this instance is the first day of week i.e. Monday.
Suppose the date is 4th July 2021 which is Sunday, then the date_trunc will result in 1st July 2021 for month and 28th June 2021 for week which is Monday inside that week.
Suppose the date is 5th July 2021 which is Monday itself, then the date_trunc will still result in 1st July 2021 for month but result in 5th July 2021 for week since it is already Monday.

Snowflake retrieving data of past month on a particular date of current month

I am new to snowflake and my manager wants me to retrieve the data of the past month when it is 5th of the current month. For example if today is 5th April, then ask snowflake to retrieve the data of the past month i.e. from 1st March 2021 to 31st March 2021 and similar for all the other months.
The reason why he wants to update the last month data on 5th of every next month because that is the day when we get the data.
I tried to use the DATEADD function but it is more complicated than just using this function.
Thanks in advance!
PS: The data for every month has same date. for example: the date is like - April 20th will be stored in the database as "2021-4-01" - and same for April 25th date will be stored as "2021-4-01" .
The day doesn't change in the database, just the month and year.
as to the prior month window that can be done via DATE_TRUNC and DATEADD
select
current_date as cd
,date_trunc('month', cd) as end_range
,dateadd('month', -1, end_range) as start_range
;
gives:
CD END_RANGE START_RANGE
2021-04-21 2021-04-01 2021-03-01
the other half of the question only do it on the 5th, if you have a task run daily etc. can be solved via
,day(current_date) = 5 as is_the_fifth
or if in an inline way
iff(day(current_date) = 5, <do true stuff>, <do false stuff>)

Postgresql extract week

Why when I run
select (EXTRACT(WEEK FROM current_date)::int )
The output is 6 - why?
Today is 2016-02-14 which is the 8th week since the start of this year.
Am I getting this result wrong?
I'm looking for a function which I give it date and it tells me what week of the year this date is.
The documentation is pretty clear on the calculation:
week
The number of the ISO 8601 week-numbering week of the year. By
definition, ISO weeks start on Mondays and the first week of a year
contains January 4 of that year. In other words, the first Thursday of
a year is in week 1 of that year.
In the ISO week-numbering system, it is possible for early-January
dates to be part of the 52nd or 53rd week of the previous year, and
for late-December dates to be part of the first week of the next year.
For example, 2005-01-01 is part of the 53rd week of year 2004, and
2006-01-01 is part of the 52nd week of year 2005, while 2012-12-31 is
part of the first week of 2013. It's recommended to use the isoyear
field together with week to get consistent results.
Weeks start on a Monday, so Sunday is the end of a week (and "today" is Sunday where I am and in most of the world at this particular time). Also, the first week depends on the when the year starts.

Get month name with different month start and end dates

Getting the month for the current date is, obviously, straight forward, but I'm needing to get the month name with a different end date.
I need to get the month name with the start date of the month being the first Thursday after the first Wednesday of the month and the end date of the month being the first Wednesday of the following month. It's for an accounting thing, so I'm not going to argue with the spec!
e.g. for 2014, January would run from 9th Jan - 5th Feb, February would run from 6th February - 5th March, March would run from 6th March - 2nd April.
I would suggest that you create a table with your 'accounting months' in it, having a start date, end date and month name columns.
You could then query this to find the row where your date is between the start and end dates and return the month name. Putting this into a scalar function would then allow it to be reusable and relatively easily updated for next years months as well.
I think, as per Paddy's answer, a lookup table is the simplest thing to do. Here's one way to generate the rows for it:
; With Numbers(n) as (
select 4 union all select 5
), Months as (
select CONVERT(date,'20010104') as StartDt,CONVERT(date,'20010207') as EndDt,
DATENAME(month,'20010103') as Month
union all
select DATEADD(week,n1.n,StartDt),DATEADD(week,n2.n,EndDt),
DATENAME(month,DATEADD(week,n1.n,StartDt))
from Months,Numbers n1,Numbers n2 --Old-skool join, just for once
where DATEPART(day,DATEADD(week,n1.n,StartDt)) between 2 and 8 and
DATEPART(day,DATEADD(week,n2.n,EndDt)) between 1 and 7 and
StartDt < '21000101'
)
select * from Months option (maxrecursion 0)
(CW since this is effectively just an extension to Paddy's answer but I don't want to edit their answer, nor is it suitable for a comment

How do I write query if I want 1st day of the month falls in 1st week in T-SQL

How do I write query if I want 1st day of the month falls in 1st week. my report needs to show data from SUN-SAT.so,
if I run the report on anyway current week, it should only show the data for the previous week from SUN-Sat.
Even though 10/27 falls in the 5th week of October , I am required to show as 10/27- 11/02 falls in the first week of November since November 1 falls in the first
week of November.
Here it is how I want to display the date-range in my report for the month of November. and the same logic applies
for every month.
Week 1 10/27 to 11/02
Week 2 11/03 to 11/09
Week 3 11/10 to 11/16
Week 4 11/17 to 11/23
Week 5 11/24 to 11/30
so, I am not counting till 4th week of October not the 5th one because I am counting 5th week as week 1 for
November.
like wise, the first week of JAN will be 12/29 till 01/04 . I don't want to count 5th week of December because if
I count, there will be duplication.
Thank you. I appreciate it.
In simpler terms, an entire week 'belongs' to a specific month based on whatever month the Saturday of that week lies in. Then you want to work backwards and calculate for a given month, the set of all weeks that belong to that month.
This will give you the forward calculation:
declare #date date = getdate();
select month(dateadd(day,7+datediff(day,#date,'2000-01-01')%7,#date))
And the reverse calculation:
declare #year int = 2013
declare #month int = 11
select
datefromparts(#year,#month,1) as month,
dateadd(day,i*7+datediff(day,datefromparts(#year,#month,1),'2000-01-01')%7-6,datefromparts(#year,#month,1)) week_start,
dateadd(day,i*7+datediff(day,datefromparts(#year,#month,1),'2000-01-01')%7 ,datefromparts(#year,#month,1)) week_end
from (values(1),(2),(3),(4),(5)) wk(i)
I use datediff(day,#date,#known_date) instead of datepart(dw,#date) because it is deterministic.