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

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>;

Related

Calculate Week Numbers based on the initial given date to end date

I have below scenario that Business want to calculate Week Number based on Given Start Date to End Date.
For Ex: Start Date = 8/24/2020 End Date = 12/31/2020 ( These Start date & end date are not constant they may change from year to year )
Expected Output below:
[Date 1 Date 2 Week Number
8/24/2020 8/30/2020 week1
8/31/2020 9/6/2020 week2
9/7/2020 9/14/2020 week3
9/15/2020 9/21/2020 week4
9/22/2020 9/28/2020 week5
9/29/2020 10/5/2020 week6
10/6/2020 10/12/2020 week7
10/13/2020 10/19/2020 week8
10/20/2020 10/26/2020 week9
10/27/2020 11/02/2020 week10
11/03/2020 11/09/2020 week11
11/10/2020 11/16/2020 week12
11/17/2020 11/23/2020 week13
11/24/2020 11/30/2020 week14
I need Oracle Query to calculate Week Number(s) like above .. Based on Start date for 7 days then week number will be calcuated.. But remember that crossing months some month have 30 days and some month 31 days etc.. How to calculate ? Appreciate your help!!
Seems your looking for custom week definition rather that built-ins. But not overly difficult. The first thing is to convert from strings to dates (if columns actually coming off table this conversion is not required), and from there let Oracle do all the calculations as you can apply arithmetic operations to dates, except adding 2 dates. Oracle will automatically handle differing number of days per month correctly.
Two methods for this request:
Use a recursive CTE (with)
with dates(start_date,end_date) as
( select date '2020-08-24' start_date
, date '2020-12-31' end_date
from dual
)
, weeks (wk, wk_start, wk_end, e_date) as
( select 1, start_date, start_date+6 ld, end_date from dates
union all
select wk+1, wk_end+1, wk_end+7, e_date
from weeks
where wk_end<e_date
)
select wk, wk_start, wk_end from weeks;
Use Oracle connect by
with dates(start_date,end_date) as
( select date '2020-08-24' start_date
, date '2020-12-31' end_date
from dual
)
select level wk
, start_date+7*(level-1) wk_start
, start_date+6+7*(level-1)
from dates
connect by level <= ceil( (end_date-start_date)/7.0);
Depend on how strict you need to be with the end date specified you may need to adjust the last row returned. Both queries do not make adjust for that. They just ensure no week begins after that date. But the last week contains the full 7 days, which may end after the specified end date.
If your date datatype is varchar then first convert it to date and then convert it back to varchar.
convert date to to_char(to_date('8/24/2020','MM/DD/YYYY'),'WW')
If you to keep week datatype as a number then you can do something like this
to_number(to_char(to_date('8/24/2020','MM/DD/YYYY'),'WW'))
Few options according to your need.
WW Week of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
W Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh.
IW Week of year (1-52 or 1-53) based on the ISO standard.

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

local week of the year in postgresql

I have to generate year wise, weekly reports for some data. Now When I aggregate date on week number, and week number is calculated from extract from creation date.
Now the problem is these both queries return week number 52.
SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-01');
SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-12-31');
First query return 52 (52nd week of 2005) and 2nd query return 52 (52nd week of year 2006). thats documented behavior.
But I want to Calculate local week number, and results for first query should be 1 and other query would return 53.
You can't do this with the exctract() function, it only supports ISO weeks.
But the to_char() function has an option for this:
SELECT to_char(DATE '2006-01-01', 'WW')::int` --> 1
SELECT to_char(DATE '2006-12-31', 'WW')::int` --> 53
For date 2006-01-01 end week is start in 2005 year, that same problem is 1999 year.
Clausule EXTRACT(WEEK getting year where week is started not ending.
You can use this code:
SELECT floor(EXTRACT(doy FROM TIMESTAMP '2006-01-01')/7 + 1);
SELECT floor(EXTRACT(doy FROM TIMESTAMP '2006-12-31')/7 + 1);

How to subtract 13 weeks from a date in PL SQL?

I have a date in sql which will always fall on a Monday and I'm subtracting 13 weeks to get a weekly report. I am trying to get the same 13 week report but for last year's figures as well.
At the moment, I'm using the following:
calendar_date >= TRUNC(sysdate) - 91
which is working fine.
I need the same for last year.
However, when I split this into calendar weeks, there will also be a partially complete week as it will include 1 or 2 days from the previous week. I need only whole weeks.
e.g. the dates that will be returned for last year will be 14-Feb-2015 to 16-May-2015. I need it to start on the Monday and be 16-Feb-2015. This will change each week as I am only interested in complete weeks...
I would do this:
Get the date by substracting 91 days as you're already doing.
Get the number of the day of the week with TO_CHAR(DATE,'d')
Add the number of days until the next monday to the date.
Something like this:
SELECT TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/YYYY')-91 + MOD(7 - TO_NUMBER(TO_CHAR(TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/RRRR')-91,'d'))+1,7) d
FROM dual
next_day - returns date of first weekday named by char.
with dates as (select to_date('16/05/2015','DD/MM/YYYY') d from dual)
select
trunc(next_day( trunc(d-91) - interval '1' second,'MONDAY'))
from dates;
I want to get next monday from calculated date. In situation when calculated date is monday i have to move back to previous week ( -1 second).

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.