How can i find the number of months between two dates in format 202101 in Hive? - hive

e.g.
I have date in format 202201, i'd like to find number of months between two dates:
202209 - 202107 <--- how can i do this given my date type is int?
I tried MONTHS_BETWEEN but it requires string in a certain format.

Use from_unixtime(unix_timestamp('202209', 'yyyyMM')) to convert to timestamp. And then use MONTHS_BETWEEN.
Whole SQL should be like this
months_between (
from_unixtime(unix_timestamp('202209', 'yyyyMM')), from_unixtime(unix_timestamp('202207', 'yyyyMM')))
If the column is an INT, you can use cast like below.
select months_between(from_unixtime(unix_timestamp(cast(202209 as STRING), 'yyyyMM')), from_unixtime(unix_timestamp(cast(202207 as STRING), 'yyyyMM')))

Related

How to extract month number from date in Oracle

I have ID_BB_SECURITY column where the date value is stored in this column for example '20190801'.
I want to get month number from this field for example for August date i want to get 8.
I tried below query but it throws an error 'literal does not match':
select to_number(to_date(ID_BB_SECURITY),'mm') from BT_EXPORT
I am not sure if i have to ignore null values so as to avoid the error
If the value is a number or string then you can convert it to a date with an appropriate mask - which is what you are missing, and what is causing the error you are getting (as it's using your session's NLS_DATE_FORMAT setting, which apparently does not match the format of the data; but which you should not rely on anyway, as #MTO said in comments):
to_date(ID_BB_SECURITY, 'YYYYMMDD')
and then extract the month number from that:
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
Or you could just use a substring:
select to_number(substr(ID_BB_SECURITY, 5, 2)) from BT_EXPORT;
Those assume a fixed consistent format, which is always a risky assumption when using the wrong data type. Ans if it's a number they are doing an implicit conversion from number to string, which you could turn into an explicit conversion for greater clarity.
If it's already a date - as it should be, of course - then you don't need the conversion:
select extract(month from ID_BB_SECURITY) from BT_EXPORT
If you have a number, you can use arithmetic to extract the month:
select mod(floor(20190801 / 100), 100)
from dual;
You could try converting the number date to a string, and then extracting the 5th and 6th characters:
SELECT
SUBSTR(TO_CHAR(ID_BB_SECURITY), 5, 2) AS mm
FROM BT_EXPORT;
But, it would be much better for you to use a proper date column. Then, you could use a less draconian method such as:
SELECT
TO_CHAR(ID_BB_SECURITY, 'mm') AS mm -- assuming date
FROM BT_EXPORT;
select to_number(to_char(to_date('20190801', 'yyyymmdd'), 'mm')) from dual
Try this one
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
This one convert number to date then extract month.
also
select extract(month from to_date('20190801', 'yyyymmdd')) from dual
Your date column has the value stored in the following format "yyyymmdd" where
yyyy is the year
mm the month
dd the day
So in order to return the number value of the month (mm) we can do as follows:
1: first transform the value from a number to a date using
to_date(20190801,'yyyymmdd')
2: get month using to_date operator
to_char( to_date(20190801,'yyyymmdd'), 'mm')

Format int as date in presto SQL

I have an integer date column "date_created" storing values like...
20180527, 20191205, 20200208
And am wondering what the best way to parse as a date is so I could do something like this in a query...
select * from table where formatted(date_created) > formatted(date_created) - 90
(to return everything within the last 90 days)
I've found some similar examples that convert from date ints representing seconds or milliseconds, but none where the columns are essentially date strings stored as integers.
Appreciate any thoughts on the best way to achieve this
And am wondering what the best way to parse as a date is so I could do something like this in a query...
You can convert "date as a number" (eg. 20180527 for May 27, 2018) using the following:
cast to varchar
parse_datetime with appropriate format
cast to date (since parse_datetime returns a timestamp)
Example:
presto> SELECT CAST(parse_datetime(CAST(20180527 AS varchar), 'yyyyMMdd') AS date);
_col0
------------
2018-05-27
However, this is not necessarily the best way to query your data. By adapting your search conditions to the format of your data (and not vice versa), you can potentially benefit from predicate push down and partition pruning. See #GordonLinoff answer for information how to do this.
You can do the comparison in the world of integers or of dates. You might as well convert the current date minus 90 days to a number:
select t.*
from t
where date_created >= cast(date_format(current_date - interval '90 day',
'%Y%m%d'
) as int
);
the below query is index friendly for any database since it does not use function on indexed column
select * from table where date_created > timestamp (formatted(date) - 90)
In addition, suppose we have date in format 20211011_1234 and we want one month older date and want back the original format, we can use the following formatting to convert date to int and vice versa.
select cast(date_format(
CAST(parse_datetime(cast(
split_part('20211011_1234', '_', 1) as varchar), 'yyyyMMdd')
AS date) - interval '30' day ,'%Y%m%d') as int) as column_name

Oracle SQL - convert a varchar2 into a date

I have a problem with converting a varchar2 fields into a date format.
I got 2 columns with the datatyp varchar2, one is called qtime the other is called ztime. Both fields contain strings in this format (f.e. 152015 -> would be a timestamp 15:20:15).
For reporting reasons I need to convert this fields into a date format, afterwards I want to substract (qtime-ztime) the fields an convert them into the format [hh] (f.e. after the operation 01:20:00 would be -> 01). Is it possible to to this within Oracle SQL 12c? The biggest problem for me right now is that I don't get those Strings converted into a date format.
select TO_DATE(qtime,'MM/DD/YYYY hh24:mi:ss') just gives me
ORA-01861:"literal does not match format string"
select TO_DATE(qtime,'hh24mmss') gives me a wrong Date
01.03.2018
select TO_TIMESTAMP(qtime,'hh24mmss') gives me a wrong Date
01.03.2018 BUT the correct time with f.e. 15:20:15,0000000
Thank you in advance, any help is appreciated
Note: I only have reading rights on the database Oracle 12c, so I need to to this within Statements
"The Database contains another column with the correct date for each time"
The missing piece of the puzzle! Concatenate the two columns to get something which can be converted to an Oracle DATE:
select to_date(qdate||qtime, 'yyyymmddhh24miss') as qdatetime
, to_date(zdate||ztime, 'yyyymmddhh24miss') as zdatetime
from your_table
Once you have done that you can perform arithmetic of the dates e.g.
select id
, zdatetime - qdatetime as time_diff
from ( select id
, to_date(qdate||qtime, 'yyyymmddhh24miss') as qdatetime
, to_date(zdate||ztime, 'yyyymmddhh24miss') as zdatetime
from your_table
)
If you want the number of hours in the difference you can include this expression in the projection of the outer query:
, extract( hour from (zdatetime - qdatetime) day to second) as hrs_ela
First off, if you are trying to convert a varchar2 into a date without specifying neither day nor month, it will default to the first day of the current month:
If you specify a date value without a date, then the default date is the first day of the current month.
You can read up more here
Also in 2nd and 3rd your example, you are using 'hh24mmss' for specifying hour, minute and second components, but do note that correct format for minutes is 'mi' and not 'mm', which is used for months.
So the solution is to concatenate both date and time component when creating the date as the other answer suggested, tho I would recommend using a single date field as it can store the information you need.

To get all the dates in a format dd/mm/yyyy. I have a date field in the format yyyymmdd

In my DB, there is a date field in the format yyyymmdd.
I have to get all the dates in the format dd-mm-yyyy for that particlar date.
ex:
Date
20170130
20170228
20170325
for the above dates, I need the output in the below format with the dates and day of the particular dates
date day
30-01-2017 tuesday
28-02-2017 tuesday
25-03-2017 saturday
If the column is a string, then it can hold invalid date values such as February 31, one way to avoid this is by a small function such as this:
create or replace
function my_to_date( p_str in varchar2 ) return date
is
begin
return to_date( p_str );
exception
when others then
return null;
end;
\\
select to_char(my_to_date('20170231'),'DD-MM-YYYY Day')
from dual
\\
Demo
Try below:
Select to_char(yrdate, 'dd-mm-yyyy'), to_char(yrdate, 'D') from yrtable
It sounds like your dates aren't actually DATE fields but some kind of CHAR field? The best option would be to convert to DATE and then convert back to CHAR:
SELECT TO_CHAR(TO_DATE(mydate, 'YYYYMMDD'), 'DD-MM-YYYY Day')
FROM mytable;
This uses the YYYYMMDD mask to convert your string into a date, then uses the mask DD-MM-YYYY Day to convert it back into a string. Use day if you want the day name in lowercase (as in your OP).
#user2778168 answer will give you the results you want. But why?
Your database does not have dates stored in yyyymmdd format or any other date format for at mater, unless it's defined with a character type definition. Oracle stores all dates in a single internal structure, and with only slight variations timestamps are the same. The format used only tells Oracle how to display the value or to convert a string to a date. Unless a specific format is specified Oracle uses the NLS_DATE_FORMAT for this determination. See here and scan down to "Datetime Format Models" for format specifications.
To see this run the following:
select value
from nls_session_parameters
where parameter = 'NLS_DATE_FORMAT';
Select yrdate default_format
, to_char(yrdate, 'dd-mm-yyyy') specified_format
, dump(yrdate) unformated
from yrtable;
alter session set nls_date_format = 'Month dd,yyyy';
Rerun the above queries.
It seems you hold date column(date1) in character format. Suppose you have a table named days:
SQL> desc days
date1 varchar2(10)
then,
we should convert it into date, and then into char format, with aliases in quotation marks to provide lowercase aliases as you wanted.
perhaps your database's date language is non-english like mine(turkish), then you need to convert it to english.
lastly, it'a appropriate to order the results according to converted date, seen from your output. So we can use the following SQL :
select to_char(to_date(date1,'yyyymmdd'),'dd-mm-yyyy') "date",
to_char(to_date(date1,'yyyymmdd'),'day','nls_date_language=english') "day"
from days
order by to_date(date1,'yyyymmdd');
D e m o

convert date to integer in postgresql

I'm trying to convert a date (date type) into int. This int should be something like the number of days since the 1 January 1900. How to get this in postgresql? In excel I'm getting this automatically when i concatenate a date with a string.
Example : 2011/11/01 convert into int as 36831
Simply subtract the two dates:
select date '2011-11-01' - date '1900-01-01'
the result will be the number of days.
More details in the manual:
http://www.postgresql.org/docs/current/static/functions-datetime.html