Find last day of the previous week in Teradata? - date

I want to find out the previous weeks's last day in Teradata SQL using Sunday as the last day of the week. For example, today is Friday 1/27, so the last week ended on Sunday (1/22) and I would want to return 2023-01-22.
Other examples:
If current date is '2023-01-02', then the output I require is '2023-01-01'
If current date is '2023-01-18', then the output I require is '2023-01-15'
With Hive query I would use:
date_sub(current_date, cast(date_format(current_date, 'u') as int));
What would the equivalent be in Teradata? I've tried using the code below but it seems to return the date of the closest Sunday instead of the date of the previous Sunday.
SELECT ROUND(current_date, 'd') (FORMAT 'yyyy-mm-dd');

There are several ways:
Probably the best one is one of the built-in functions to return the previous xxxday <= the input date:
Td_Sunday(Current_Date - 1)
Or the function to return the next xxxday > input date:
Next_Day(Current_Date - 8, 'sun')
Truncating is least understandable:
Trunc(Current_Date, 'IW') -1
TRUNC supports three variations, only IW is usable, but restricted to Monday as week start:
IW: the Monday of the ISO week
WW: the same day of the week as January 1st of the year
W: the same day of the week as the first day of the month

You can use the trunc function to return the first day of the a week, month, ect.
select trunc(current_date -7 ,'IW')
Current date today is 2023-01-27. This will return 2023-01-15, the previous Sunday.
EDIT: Sorry, meant to use the ISO week. As Dnoeth points out, the regular week option doesn't work consistently (which I didn't know, never used it for this before). Anyhoo, his answer is better than mine...

Related

Azure Synapse Pipeline Date Expression - Last Monday

I have the following azure function that is supposed to retrieve the date of the previous Monday. It works fine except for if the current date is a monday. I need the function to still retrieve the previous monday date if it is Monday or Tuesday. This is due to the time not being updated until middle of day tuesday.
#{formatDateTime( subtractFromTime( utcNow(), sub(dayOfWeek(utcNow()),1), 'Day' ), 'yyyy-MM-dd 00:00:00' )}
I am still learning Azure synapse so I am not sure if I can write an IF statement that accomplishes this or if there is a better way to write it.
I have reproduced the above and able to get the desired result by using the below dynamic content.
#if(greater(dayOfWeek(utcnow()),1),formatDateTime(addDays(subtractFromTime(utcnow(),dayOfWeek(utcnow()),'Day'),1),'yyyy/MM/dd'),formatDateTime(addDays(subtractFromTime(utcnow(),dayOfWeek(utcnow()),'Day'),-6),'yyyy/MM/dd'))
The day of week for a monday from last sunday is 1, so I am checking the current date's day of week is greater than monday or not.
If it is greater (Today is not a Monday), then I am giving last Monday by adding 1 day to the last Sunday.
If it is not, then I am subtracting -6 from the last Sunday which is the previous Monday.
This will work for all days, but we need to change the condition and the number which we are adding and subtracting as per the day we required.
Result:
If you want the result to be Monday even though current date is Monday or Tuesday, then give the expression for Tuesday also in the above condition using or.

Start of Week in Amazon Redshift (Sunday Start of the Week)

I need to convert Week to start with Sunday (range 1-53, with a Sunday in this year)
Ex. DATE_PART(w,'2020-01-05') (Sunday)
This should return 2 instead of 1.
Thanks in advance.
If you wish to obtain the Week Number where a week starts on Monday instead of Sunday:
Subtract one day to the date being convert to the Week Number
So, use:
DATE_PART(w, date_field - INTERVAL '1 DAY')
This returns the Week Number of the 'previous day'.
Unfortunately, it won't work for the first day of the year, which will appear to be the last day of the previous year. Depending on how your organization treats the first/last weeks of the year, this might be okay.
If that is not satisfactory, then you could write your own User-Defined Function (UDF) and code it to return the values you desire.

TSQL ISO Month Week Number for ISO Year Week Number

Using TSQL I need to get the ISO Week Number in a Month for a give ISO Year Week Number.
For example: The following code will give me Week #1 for 12/31/2001, which is correct. It is the first Monday in 2002 and the first day of the ISO Year 2002.
select DATEPART(ISO_WEEK, '12-31-2001'); --Week 1 January 2002
My question is how do I...
(1) Take the ISO Week Number Example: ISO Year Week Number: 14 for April 4, 2016 (April Week #1).
(2) Now Take ISO Year Week Number 14 and return April Month Week Number = 1 for the example above.
There seems to be nothing in SQL Server to get the ISO Month Week# from the ISO Year Week Number. I have a function I wrote but it is has some hacks to get it to work, but not 100%.
I think you want something like this... but am not sure why you need the ISO_WEEK. Just replace getdate() with your column.
select datepart(wk, getdate()) - datepart(wk,dateadd(m, DATEDIFF(M, 0, getdate()), 0)) + 1
After attempting to handle getting ISO Month Week Number in functions I decided an easier solution was to create an ISO_Calendar table in SQL Sever.
We know in TSQL you can get the ISO Year Week Number and some a bit of work the ISO Year Number. The ISO Month Week Number is another story.
I build the table shown below with data from 2000 to 2040 by populating all the columns other than the ISO Month number. Then on a second pass I looped through the table and set the ISO Month number based on the Month# in the Monday Date.
Now if I want to get the ISO Month number for a date I check #Date between Monday and Sunday. In my case I am only concerned with dates between Monday and Friday since this is for a stock analysis site.
select #ISOMonthWeekNo = c.ISOMonthWeekNo
from ISO_Calendar c
where #TransDate between c.Monday and c.Sunday;
The advantage is the table is a one time build and easier to verify the accuracy of the data.

MS Access / forcing a date range 2 months back, bound to this week

I have a query where I need, as date criteria, the week ending two months prior.
So for example if I ran the query on Monday (as of right now, the last Monday was 2/1/2016), it would look at 11/29/2015 through 12/5/2015 inclusive (Sunday through Saturday).
And then next week if I ran it, it would focus on 12/6/2015 through 12/12/2015 (Sunday through Saturday).
However I need it to return this exact same date range no matter which weekday of the week I run it. So for example the date range 11/29/2015 through 12/5/2015 would be selected if I ran it on 2/1/2016 through 2/5/2016 (Mon-Fri).
I'm not sure what the best way is to go about this. I've considered somehow trying to find the next Saturday and then clocking that back a few weeks, but there doesn't seem to be a week option in dateadd().
To get the first weekday of a week from Sunday to Saturday:
FirstWeekDate = DateAdd("d", 1 - Weekday(Date()), Date())
To go back, say 8 weeks:
EightWeeksBack = DateAdd("ww", -8, FirstWeekDate)
Then you can just add/subtrack days to get your intervals, for example.
EightWeeksBackLast = DateAdd("d", 6, DateAdd("ww", -8, FirstWeekDate))

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.