Postgresql extract week - sql

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.

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.

BigQuery Standard SQL returns different WEEK from timestamp

I am converting an old query from Legacy SQL to Standard SQL and noticed my report was off. I've traced it back to Legacy SQL and Standard SQL returning different weeks based off of a UNIX millisecond timestamp.
I was under the impression the Legacy SQL query was correct, but however, I'm curious to know the difference. It's not across all weeks, but enough to throw my report off significantly.
Here's an example:
#legacySQL
SELECT WEEK(MSEC_TO_TIMESTAMP(1470631859000)) AS sign_up_week;
Output: 33
#standardSQL
SELECT EXTRACT(WEEK FROM TIMESTAMP_MILLIS(1470631859000));
Output: 32
I've viewed the following documentation on the Legacy SQL reference:
WEEK(<timestamp>)
Returns the week of a TIMESTAMP data type as an integer between 1 and 53, inclusively.
Weeks begin on Sunday, so if January 1 is on a day other than Sunday, week 1 has fewer than 7 days and the first Sunday of the year is the first day of week 2.
And from the Standard SQL reference:
WEEK(<WEEKDAY>): Returns the week number of the date in the range [0, 53]. Weeks begin on WEEKDAY. Dates prior to the first WEEKDAY of the year are in week 0. Valid values for WEEKDAY are SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY.
ISOWEEK: Returns the ISO 8601 week number of the date_expression. ISOWEEKs begin on Monday. Return values are in the range [1, 53]. The first ISOWEEK of each ISO year begins on the Monday before the first Thursday of the Gregorian calendar year.
How can I get my Standard SQL query to output the same week number as my Legacy SQL query? If not, which week number is correct? It does not appear I can get them to dovetail natively.
This is a bit subtle, but legacy and standard SQL handle weeks differently. In Legacy SQL:
Weeks begin on Sunday, so if January 1 is on a day other than Sunday, week 1 has fewer than 7 days and the first Sunday of the year is the first day of week 2.
In Standard SQL:
WEEK: Returns the week number of the date in the range [0, 53]. Weeks begin with Sunday, and dates prior to the first Sunday of the year are in week 0.
So, in Legacy SQL the first Sunday is week 2. In Standard SQL, the first Sunday is week 1.

How can I Format the Date so that the fiscal week starts in December?

I want to format a date as follows: Y17W15, but there is no option to set the start of the year. However, there is no consistent way of calculating this. I cannot just subtract a month (other times I will need to show the month too), and I cannot just add 4 or 5 to the week field due to leap years, etc.
Our year starts on a Saturday that is closest to December 1. This means if November 30 is on a Saturday, the Fiscal Year will start on November 30.
Currently what I have is below, which works fine except it shows Y17W10. The easiest option in my head is to have a way to actually set the start of a fiscal year, but if I have to go through a bunch of if statements it's okay as long as it works.
MsgBox(Format(Now, """Y""yy""W""mm"""))
Thanks for your time!
I am aware that: Given a 4-5-4 calendar and a date, how do I determine what fiscal week that date falls in? exists but I am looking for an answer that isn't as hard-coded.
Michael

What exactly does trunc(date, 'IW')?

For my project I need to have an absolute numerical correspondence between days of the week and 1...7 values.
As you probably know the association between days and numbers can vary according to the locale, for example in Germany Monday is 1 and Sunday is 7, while in US Monday is 2 while Sunday is 1.
So, searching for a solution, I found the following code which seems working regardless of the locale, assigning Monday=1...Sunday=7:
1 + TRUNC (date) - TRUNC (date, 'IW')
Can someone explain me how does it work? In particular I just can't understand what this instruction:
TRUNC (date, 'IW')
exactly does.
TRUNC(DATE,'IW') returns the first day of the week. For me TRUNC(SYSDATE,'IW) returns Monday. Today is Tuesday Feb 21. Subtract from that TRUNC(SYSDATE,'IW') which would be Monday the 20th, and you'll get 1 (because 21-20=1). Add 1 onto that as you do in the beginning of your equation and you get 2, which we associate with Tuesday.
The very basic concept of ISO week is to make it NLS territory independent.
From documentation,
Week of year (1-52 or 1-53) based on the ISO standard.
A week starts on a Monday and ends on a Sunday.

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.