Convert string to date with added time Oracle - sql

I have two values I want to compare. Samples of those are the following:
'01/04/2020T07.08.45'
'2020-04-01 14:46'
I want to transform the first value into the same mask as the second, so I can use it to join two tables lateron.
The first value is saved in a different time-zone than the second. I also need to convert that by adding two hours to the first value, depending on the moment I ran the comparasing.
Using substring didn't solve my problem as I wasn't able to add two hours to a string. The to_date function also didn't brought me anything.
Can you help me?

You have to convert both values to the date.
TO_DATE('2020-04-01 14:46', 'YYYY-MM-DD HH24:MI');
TO_DATE('01/04/2020T07.08.45', 'DD/MM/YYYYTZH.HH24.MI')
I'm not sure about the date that contains a timezone.

Related

Extract year from timestamp in hive

I am writing the query to show the data entries for a specific year. Date is stored in dd/mm/yyyy hh:mm:ss.(Date TIMESTAMP - e.g. 12/2/2014 0:00:00).
I am trying to display the two columns(name, orderdate) filtered by a specific year(year from orderdate). The requirement is to enter the specific year(2010 or 2020 etc) not the entire date. I tried using date_format() and regexp_replace() with WHERE but nothing helped.
Can someone help me?
If your are storing the date -- incorrectly -- as a string, then you can use string functions to do what you want:
where orderdate like '__/__/2010%'
However, you should really put your effort into storing the date using a correct format -- YYYY-MM-DD for strings at least.

Unable to get data between two years

I am not getting data between two years, below is between condition
to_char(Wfc.APPLYDTM,'MM/DD/YYYY') between '12/11/2019' and '01/10/2020'
but I am getting data between '12/11/2019' and '12/31/2019' & '01/11/2020' and '01/01/2020' for these dates but not between two different years.
Please help
Try using TO_DATE instead of TO_CHAR, and then compare against valid Oracle date literals:
SELECT *
FROM Wfc
WHERE TO_DATE(APPLYDTM, 'MM/DD/YYYY') BETWEEN date '2019-12-11' AND date '2019-01-10';
Note that if APPLYDTM already be a date, then you don't need to call TO_DATE on it. It doesn't make sense to convert your data to character, if you intend to work with it as a date.
You should convert your data to Date to be able to compare correctly.
The main idea is you should compare date value instead of string value.
to_date(Wfc.APPLYDTM,'MM/dd/yyyy') between to_date('12/11/2019','MM/dd/yyyy') and to_date('01/10/2020','MM/dd/yyyy')
Read here to more details.
Do not convert date/time values to strings! Use the built in functionality.
Your logic is most simply expressed as:
Wfc.APPLYDTMbetween >= DATE '2019-12-11' AND
Wfc.APPLYDTMbetween < DATE '2020-01-11'
Note that the date constants are provided using the DATE keyword. This supposed ISO 8601 standard date formats (happily!).
Also note the use of >= and < rather than BETWEEN. The date data type in Oracle can include a time component -- even if you don't see it when you query the table. This ensures that all date/times are included in the range.
As an added benefit, this can use an index on (APPLYDTMbetween). Using a function usually precludes using an index, unless you have defined a function-based index.

Transform every row in a column to date, using first unix_timestamp

I have rows with the following format and I would like to transform then into valid Hive timestamps. Format in my data:
28/04/2017 00:00:00|20550|22/05/2017 00:00:00|
I'm only interested in the first and third column, separated with |, in MY case the format is, then:
dd/MM/yy HH:mm:ss
I've discovered this can't be used as timestamp in Hive.
I find myself unable to transform all that first and third column to the proper format using queries similar to:
select from_unixtime(unix_timestamp('28/04/2017','dd/MM/yy HH:mm:ss'),'yyyy-MM-dd') from `20170428_f_pers_pers`
I'm trying different instances of that query but since I can't access the documentation (internet is capped here at work), I can't see how to properly use this two functions, from_unixtime and unix_timestamp
I've made the following assumptions:
I can reorder the days and years. If this isn't true, I have no idea how to transform my original data into proper Hive format
When I do this select, it affects the whole column. Further, after doing this with success I should be able to change the format of the whole column from string to timestamp (maybe I have to create a new column for that, not sure)
I do not care about doing both columns at once, but right now when I do the query showed first I get as many nulls as data has my table, and I'm unsure my assumptions are even partially right since every example I come accross is simpler (they do not change days and years arround, for instance).
I would like to know how to apply the query to a specific column, since I haven't understood how to do that from the examples studied so far. I do not see them using any type of column ID for that, which is weird to me, using data from the column to change the column itself.
Thanks in advance.
edit: I am now trying something like
select from_unixtime(unix_timestamp(f_Date, 'dd/MM/yyyy HH:mm:ss')) from `myTable`
But I get from HUE the following error:
Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
The format should be completely covered by the input string.
In other words -
The format can be equal in length to the the input string or shorter, but not longer.
28/04/2017 00:00:00
|||||||||||||||||||
dd/MM/yyyy HH:mm:ss
select from_unixtime(to_unix_timestamp('28/04/2017 00:00:00', 'dd/MM/yyyy HH:mm:ss'))
2017-04-28 00:00:00
28/04/2017 00:00:00
||||||||||
dd/MM/yyyy
select from_unixtime(to_unix_timestamp('28/04/2017 00:00:00', 'dd/MM/yyyy'))
2017-04-28 00:00:00
The result can be converted from string to timestamp using cast
select cast (from_unixtime(to_unix_timestamp('28/04/2017 00:00:00', 'dd/MM/yyyy HH:mm:ss')) as timestamp)

PLSQL: Query star schema time-dimension without stored date

I have a star schema database with an Hour-Dimension (Time-dimension), with the following columns in it:
ID, ON_HOUR, ON_DAY, IN_MONTH, IN_YEAR
I then query the database, and I want to find all entries within an interval of given dates, based on this Hour-Dimension.
However comparing the ON_DAY attribute with the interval days and so on with IN_MONTH and IN_YEAR, I can often reach a case where I receive no data, if the interval spans over several months. Thus I need to convert these values to a timestamp, however I am querying into the database, so how do I compare my given timestamps with the time data properly? I do not have a stored DATE nor TIMESTAMP in the database - should I change this?
Right now, my best bet is something like this:
to_timestamp('H.IN_YEAR-H.IN_MONTH-H.ON_DAY H.ON_HOUR:00:00', 'YYYY-MM-DD hh24:mi:ss')
This does not seem to work however, and it also looks dodgy, so I didn't really expect it to...
What is the best way to get the entries within my given interval of dates?
You appear to be passing a literal string into the timestamp function - you need to pass in the values as a concatenated string using the concat function. Try the below code snippet
(H.IN_YEAR||H-IN_MONTH||H.ON_DAY||H.ON_HOUR,'YYYMMDDHH24')

Fetching the records which are having all time stamp columns

I am trying to fetch the records which are having all time stamp columns.
I am using the following query to fetch the products that are created between the final date and (final date - 30) days, i.e products created during the last 30 days that fall in the 'final date' range.
I have products that are created on 30-OCT-2014. For the same products, the initiated date is 12-NOV-2014. However they are not being fetched when I using the below query.
SELECT A.ROW_ID,
A.PROD_NAME
FROM PROD A,
PROD_REL B
WHERE A.ROW_ID = B.PAR_ROW_ID
AND TO_DATE(A.CREATED_DT,'YYYY-MM-DD') BETWEEN (TO_DATE(B.FINAL_DATE,'YYYY-MM-DD') - 30)
AND (TO_DATE(B.FINAL_DATE,'YYYY-MM-DD'));
So, could you please let me know if I am missing something?
Here is a link to a SQLFiddle that demonstrates the problem.
… or just fix your format string TO_DATE(A.CREATED,'DD-MON-YYYY')
SQL Fiddle
Storing dates as DATE, is , of course, always a good starting point.
Since your data types are all dates, there is no need to use to_date. It's harmful, in fact, since to_date doesn't take a date as a parameter. Oracle has to do an implicit conversion from a date to a string, using your session's NLS_DATE_FORMAT which gets passed in to to_date and converted back to a date using the explicit format mask you specified. If the two conversions aren't using the same format mask, bad things happen.
Your WHERE clause just needs to be
AND a.created_dt BETWEEN b.final_date - 30
AND b.final_date
If I make that change, your SQLFiddle returns two rows