Why is extract week from current_date giving wrong week number - sql

select extract(week from current_date) is giving 16 but current ISO week is 17.
Is this a bug or am I doing something wrong? Last week it worked OK.

You might be looking for:
extract(isoweek from current_date)
As per the documentation:
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.
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.

Related

How to get the start date of the week by week number of year in Hive? First day of week should be Monday

I have a week number of year in ISO format and I want to get start date of this week in Hive. First date of week is Monday.
Example: year 2020 week 50 - start date should be 2020-12-07
Try the code below, where year and week are the corresponding column names of your table.
select date(
from_unixtime(
unix_timestamp(concat(year,'-',week,'-','1'), 'yyyy-w-u')
)
) from <your_table_name>;

Difference of timestamp event rows using WHERE clause

I have two event tables with timestamped data: Registered, Signed_In.
Both have rows such as: original_timestamp, user_id
I am trying to find out users who haven't signed in within 30 days after registering. I have used the following query but I cannot add a WHERE clause to it.
I tried a query but I am getting hourly difference, whereas I wanted days difference which is unsupported in BigQuery.
SELECT Signed_In.user_id, TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, HOUR) AS days_difference
FROM `test_db.Signed_In` signed_in
JOIN `test_db.Registered` registered
ON Signed_In.user_id = Registered.user_id
GROUP BY 1,2
ORDER BY 2 DESC
WHERE days_difference > '30'
I am getting two columns: user_id, days_difference but the days_difference shows hours and my WHERE clause is rejected when I use it.
You can try this below code-
Note: Using Ordinal Position for GROUP BY and ORDER BY is not a good practice. Its always safe and standard to use the column names directly.
SELECT Signed_In.user_id,
TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, HOUR) AS days_difference
FROM `test_db.Signed_In` signed_in
JOIN `test_db.Registered` registered
ON Signed_In.user_id = Registered.user_id
WHERE DATE_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, Day) > '30'
GROUP BY 1,2
ORDER BY 2 DESC
Just replace HOUR to DAY in your query:
SELECT Signed_In.user_id, TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, DAY) AS days_difference
Correct values are:
MICROSECOND
MILLISECOND
SECOND
MINUTE
HOUR
DAYOFWEEK
DAY
DAYOFYEAR
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.
WEEK(<WEEKDAY>): Returns the week number of timestamp_expression in the range [0, 53]. Weeks begin on WEEKDAY. datetimes 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 datetime_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.
MONTH
QUARTER
YEAR
ISOYEAR: Returns the ISO 8601 week-numbering year, which is the Gregorian calendar year containing the Thursday of the week to which date_expression belongs.
DATE
DATETIME
TIME

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.

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.

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.