Yearweek and yearmonth to date in BigQuery - google-bigquery

I have the following date formats:
Yearweek Yearmonth
202053 202012
How could I turn them into dates? For example, 202053 will become 2020-12-28 (that's the first day of this week), and 202012 will become 2020-12-01.

A format string for ISO year and ISO week is %G and %V respectively, so below query is expected to work but fails with no reason (seems to me at least)
SELECT PARSE_DATE('%G%V', '202053')
Failed to parse input string "202053"
To workaround this, you can modify a Yearweek string like below,
SELECT PARSE_DATE('%G-%V' '2020-53') AS yearweek_dt
Yearmonth has no issue, so putting two things together:
WITH sample_data AS (
SELECT '202053' Yearweek, '202012' Yearmonth
)
SELECT PARSE_DATE('%G-%V', LEFT(Yearweek, 4) || '-' || RIGHT(Yearweek, 2)) AS yearweek_dt,
PARSE_DATE('%Y%m', Yearmonth) yearmonth_dt
FROM sample_data;
you will get following result:

Related

Is there a way to convert a yyyy/mm varchar data to date format in snowflake? [duplicate]

This question already has an answer here:
Split quarters to individual months
(1 answer)
Closed 3 months ago.
I need to convert a yyyy/dd varchar type data( ex: 2021/03) to a monthly sort of date. (Ex: 2021/01, 2021/02, 2021/03). So, i need to convert the quarterly format to a monthly format in snowflake. Can we do this?
I tried many things but didn't get the expected results
select TO_DATE(date_column, 'YYYY/MM')
It may help to have a calendar table in your environment to deal with more complicated date conversions like this. An example of what this table may look like is in this CTE below. The SELECT statement following converts a string date of format YYYY/QQ of '2021/03' to YYYY/MM
WITH calendar AS
(
SELECT
dateadd('DAY', seq4(), '2000-01-01'::DATE) as calendar_date,
MONTH(calendar_date) as month_of_year,
QUARTER(calendar_date) as quarter_of_year,
YEAR(calendar_date) as year_of_calendar,
DAY(calendar_date) as day_of_month,
WEEK(calendar_date) as week_of_year
FROM table(generator(rowcount => 365*50))
)
SELECT DISTINCT '2021/03' as YYYYQQ_date,
year_of_calendar || '/' || LPAD(month_of_year, 2, '0') as YYYYMM
FROM calendar
WHERE year_of_calendar = strtok(YYYYQQ_date, '/', 1)
AND quarter_of_year = strtok(YYYYQQ_date, '/', 2);
2021/07
2021/08
2021/09
That's merely an example for turning yyyy/qq into multiple yyyy/mm outputs for that quarter, but this same logic can be applied to any date-part conversion and the calendar table can be customized to hold even organization-specific date things like oddball fiscal periods, company holiday flags, or a business day flag (as an example).

How to convert an int to DateTime in BigQuery

I have an INT64 column called "Date" which contains many different numbers like: "20210209" or "20200305". I want to turn those numbers into a date with this format: MM-YYYY (so in these cases, 02-2021 and 03-2020). Ultimately I want to sum all the data in each month together. The problem is that BigQuery can't convert INT64 to date, only to strings. I'm not sure if I should convert to a string and then to a date or if there is a better way.
Although converting to a string then a date both works and is very concise, over large enough numbers of rows (which may be the case in Big Query) you may be better off using integer maths and using DATE(year, month, day)...
https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
SELECT
DATE(
DIV( 20210209 , 10000), -- Which gives 2021
DIV(MOD(20210209, 10000), 100), -- Which gives 02
MOD(20210209, 100) -- Which gives 09
)
You can convert the value to a string and use parse_date():
select parse_date('%Y%m%d', cast(20210209 as string))
Another option
select date,
regexp_replace('' || date, r'(\d{4})(\d{2})(\d{2})', r'\2-\1') as MM_YYYY
from your_table
if applied to sample data in your question - output is
Yet another option
select date,
format_date('%m-%Y', parse_date('%Y%m%d', '' || date)) as MM_YYYY
from your_table
with same output

How to convert an YYYY-MM-DD date to YYYY-MM date

In SQL. How to convert a column A from (YYYY-MM-DD) to (YYYYMM)? I want to show the dates in YYYYMM format instead of YYYY-MM-DD.
Data type is TIMESTAMP. Using Teradata Studio 15.10.10.
For Teradata either use
to_char(tscol, 'YYYYMM') -- varchar result
or
extract(year from tscol) * 100 + extract(month from tscol) -- integer result
In Teradata you can format dates pretty much at will. To get YYYYMM, you would use
select <your date> (format 'yyyymm') (char(6))
Your date column needs to be actual date for this, not a string.
There are 3 functions you'll need.
MONTH() function. Returns the MONTH for the date within a range of 1 to 12 ( January to December). It Returns 0 when MONTH part for the date is 0.
YEAR() function. Returns a 4 digit YEAR.
CONCAT() function is used to concatenate two or more strings together.
So here's an example of combining the 3 functions.
SELECT CONCAT(YEAR('1969-02-18'),MONTH('1969-02-18'))
or you can do it in one with
select DATE_FORMAT('1969-02-18','%Y%m')
So to answer your question if it is referring to column A, you can use
SELECT DATE_FORMAT(A,'%Y%m')
SQL Fiddle:
http://www.sqlfiddle.com/#!9/a6c585/48362
You can use DATEPART to get the year and month parts of the date, cast to a varchar, pad and the concaternate.
SELECT DATEPART(YEAR,GETDATE())
SELECT DATEPART(MONTH,GETDATE())
SELECT CAST(DATEPART(YEAR,GETDATE()) AS VARCHAR(4)) + RIGHT('00' + CAST(DATEPART(MONTH,GETDATE()) AS VARCHAR(2)),2)

Selecting YYYYMM of the previous month in HIVE

I am using Hive, so the SQL syntax might be slightly different. How do I get the data from the previous month? For example, if today is 2015-04-30, I need the data from March in this format 201503? Thanks!
select
employee_id, hours,
previous_month_date--YYYYMM,
from
employees
where
previous_month_date = cast(FROM_UNIXTIME(UNIX_TIMESTAMP(),'yyyy-MM-dd') as int)
From experience, it's safer to use DATE_ADD(Today, -1-Day(Today)) to compute last-day-of-previous-month without having to worry about edge cases. From there you can do what you want e.g.
select
from_unixtime(unix_timestamp(), 'yyyy-MM-dd') as TODAY,
date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)) as LAST_DAY_PREV_MONTH,
substr(date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)), 1,7) as PREV_MONTH,
cast(substr(regexp_replace(date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)), '-',''), 1,6) as int) as PREV_MONTH_NUM
from WHATEVER limit 1
-- today last_day_prev_month prev_month prev_month_num
-- 2015-08-13 2015-07-30 2015-07 201507
See Hive documentation about date functions, string functions etc.
below works across year boundaries w/o complex calcs:
date_format(add_months(current_date, -1), 'yyyyMM') --previous month's yyyyMM
in general,
date_format(add_months(current_date, -n), 'yyyyMM') --previous n-th month's yyyyMM
use proper sign for needed direction (back/ahead)
You could do (year('2015-04-30')*100+month('2015-04-30'))-1 for the above mentioned date, it will return 201503 or something like (year(from_unixtime(unix_timestamp()))*100+month(from_unixtime(unix_timestamp())))-1 for today's previous month. Assuming your date column is in 'yyyy-mm-dd' format you can use the first example and substitute the date string with your table column name; for any other format the second example will do, add the column name in the unix_timestamp() operator.
Angelo's reply is a good start but it returns 201500 if the original date was 2015-01-XX. Building on his answer, I suggest using the following:
IF(month(${DATE}) = 1,
(year(${DATE})-1)*100 + 12,
year(${DATE})*100 + month(${DATE})-1
) as month_key
provided you get rid of those hyphens in your input string , previous date's month id in YYYYMM format you can get by:-
select if( ((${hiveconf:MonthId}-1)%100)=0 ,${hiveconf:MonthId}-89,${hiveconf:MonthId}-1 ) as PreviousMonthId;

order by not formatted date sqlite

I'm storing Dates as string in the database with this format DD-MM-YYYY.
When I tried to make a select query with an orderby on the date column. I didn't get the expected result.
example of result :
28/02/2013
27/02/2013
01/03/2013
My sql query :
SELECT * FROM data ORDER BY strftime('%s', date_column)
Thank you.
The problem is that you store dates as DD-MM-YYYY strings, which does not only prevent natural ordering of dates as strings, but also parsing them with SQLite's date and time functions. Click the link and scroll down to 'Time Strings' section.
SQLite expects date/time strings in the natural order, most significant digit to least significant, that is, YYYY-MM-DD. You can use string operations to transform your DD-MM-YYYY strings into that form. For instance:
select
substr(reversed_date, 7,4) || '-' ||
substr(reversed_date, 4, 2)|| '-' ||
substr(reversed_date, 1, 2) as proper_date
from (
select '12-03-2000' as reversed_date
)
;
You can either transform your date column into this format (as #peterm suggests) or just use the value of proper_date for sorting. You don't need to use strftime for that, but date-related functions will work with such values.
IMHO you need to change the format you store dates in from
DD-MM-YYYY
to
YYYY-MM-DD
From docs
Time Strings
A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
...
Then your original query and this one will work as expected
SELECT * FROM Table1 ORDER BY date(date_column);
SELECT * FROM Table1 ORDER BY strftime('%s', date_column);
Output:
| date_column |
---------------
| 2013-02-27 |
| 2013-02-28 |
| 2013-03-01 |
sqlfiddle
According to the documentation the following should work
SELECT *
FROM data
ORDER BY strftime('%Y-%m-%d', date_column)
try:
SELECT * FROM data ORDER BY to_date(date_column)
probably this might solve you problem as it is going for string comparison rather than date comparison so
01/03/2013 appears smaller than 28/02/2013 or 27/02/2013
thus output is :
01/03/2013, 27/02/2013, 28/02/2013
This query worked for me filter dates
SELECT inst.*,
Substr(columnname, 4, 2) AS newdate,
Substr(columnname, 0, 3) AS newday,
Substr(columnname, 12, 5) AS newtime
FROM table_name AS inst
WHERE child_id = id
ORDER BY newdate DESC, newday DESC, newtime DESC