Oracle : Want to convert Substring to a useable, sortable date - oracle

1st Post go easy on me.
I'm using this Substring to pull part of a Field, this date I assume is probably non Standard (ddmmmyy) - how can I enhance this command so that I can use this a sortable Date Field, I'm guessing Cast but have no idea of Syntax etc ??
SELECT SUBSTR(Host_Name,-9) as Decom_Date
Output
DECOM_DATE
31Oct2018
31May2018
31May2018
31Mar2017
31Jul2018
TIA

This is exactly what the TO_DATE function is designed for:
SELECT TO_DATE(SUBSTR(Host_Name,-9), 'DDMonYYYY') as Decom_Date
It doesn't affect you here but bear in mind that oracle dates can only store down to a second precision. Also, if you have any rogue data in the table that can't be cant be parsed as a date you'll get "not a valid..." or "a nonnumeric was found where a numeric was expected".
Be mindful that your strings here are in English but parsing MON (3 letter month name) can be regionally contextual so this code might not work on a server with a different NLS; for example consider passing 'NLS_DATE_LANGUAGE = American' as the third argument to TO_DATE if you know your strings will always be English month names

Related

Changing format of date without using to_char - Oracle

I have to get the max payment date on an invoice and I am having trouble with the date format. I do not need the max in this formula as I am using the format in a reporting tool that is pulling the max from what it finds for me.
Using "to_char({datefield},'mm/dd/yyyy')" works for displaying that date the way we would like BUT when you use summary function MAX it does not pull the correct date because it is looking at a string and not a date (it will think 12/3/21 is larger than 3/2/22).
Another thing I have tried is trunc - "trunc({datefield})" which gives us the correct max date but it changes the formatting. For example if the date prior to the formula being applied is "8/12/21 12:00:00:000" the trunc formula will display it as 12-08-21 which is horribly wrong.
Long story short is I need a way to change a date/time to date with the format of 'mmmm/dd/yyyy' WITHOUT converting it to a string with something like to_char. Thank you!!!!
A DATE is a binary data type consisting of 7 bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has all of those components and it is NEVER stored with any (human-readable) format.
What you are seeing when a date is displayed is the client application you are using to access the database making a decision to be helpful to you, the user, and display the binary DATE provided by the database in a human-readable format.
If you want to change how the DATE is displayed then you either need to:
Change the settings on the client application that controls how it formats dates when it displays them to you; or
Change the data-type so that it is no longer a DATE (which does not have a format) to a data type where the values of the date can be formatted (such as a string). You can do this using TO_CHAR.
If you want to find the maximum then do it BEFORE applying the formatting:
SELECT TO_CHAR(MAX({datefield}),'mm/dd/yyyy')
FROM your_table;

Hive: filtering data between specified dates in string format. Which one is optimised and why?

Which one should be preferred and why? My_date_column is of type string and of format YYYY-MM-DD
SELECT *
FROM my_table
WHERE my_date_column >= '2019-08-31' AND your_date_column <= '2019-09-02';
OR
SELECT *
FROM my_table
WHERE my_date_column in ('2019-08-31','2019-09-01','2019-09-02') ;
Lastly, In general, should I be storing my date as Date data type or simply as a string? I chose string type simply to handle any corrupt/badly formatted data.
Always store dates as date type. If you store them as strings it adds overhead to do any kind of arithmetic with the values (including those inequalities).
If you decided to ignore this advice and store dates as string anyway, then I believe the second form (the IN list) will be faster as it is comparing text string against text string. The other option, using inequalities, may not give the results you expect unless you explicitly CAST(my_date_column as date) and CAST(your_date_column as date). Those cast will be applied to every record, which adds to the total cost of the query, and would be avoidable if those columns were stored as date instead.
A third option that you didn't mention is to use the BETWEEN operator (ie. WHERE my_date BETWEEN start_date AND end_date). This is the same as using the two inequalities, but probably a bit cleaner and more idiomatic.
When in doubt, take a look at the EXPLAIN plans to understand how the query will be executed.

Funky timestamp format

We are getting data from a vendor, and loading it into Hive. I am unable to cast a date-time field as timestamp (It's all stored as strings). After bashing my head against it for a while, I've finally noticed that there is an hyphen between the day portion of the date and the hour portion of the time:
yyyy-mm-dd-hh.mm.ss.SSSSSS
2016-05-18-21.05.21.177152
I've been trying to work out a way to handle this with from_unixtime, but no luck so far. I'm pretty sure that's not a valid pattern for a SimpleDateFormat.
Is there any way to handle this that doesn't involve splitting it apart into two strings, and concatenating them back into a valid pattern?
Split the date using substr and replace the '-' in the second part of the string and concat both string.
from_unixtime(concat(substr(sdate,0,10)),regexp_replace(substr(sdate,10,16),'-','')))

OBIEE: Casting String to date then date to string

FILTER("source"."recordCount" USING "source"."snapshot_date" =
EVALUATE('TO_CHAR(%1, ''YYYYMMDD'')', TIMESTAMPADD(SQL_TSI_DAY, -7, EVALUATE('TO_DATE(%1, %2)', "source"."snapshot_date" , 'YYYYMMDD'))))
So i have this piece of code here. I know some will say "Just use the AGO function" But somehow it's causing problems because of it's connection with other tables so what I'm trying to achieve here is like a remake. The process goes this way:
The snapshot_date there is actually in varchar format and not date. So it's like "20131016" and I'm trying to change it to a date then subtract 7 days from it using the TIMESTAMPADD function and then finally returning it back to varchar to use it with FILTER.
This snippet somehow works when testing the FILTER using hardcoded values like "20131016" for example but when tested out with the code above all the row are blank. On paper, the process i assumed would happen goes lke this. "20131016" turns to a date with a format of 20131016 (yyyymmdd) and then less 7 days: 20131009 and then turned into char again "20131009" to be used in the filter.
But somehow that doesn't happen. I think the data format is not applying either to the string->date or the date->string conversion. which results to the values not getting a match at all.
Anyone have any idea what's wrong with my code?
By the way I've already tried to use CAST instead of EVALUATE or TO_TIMEDATE with the same result. Oh and this goes to the formula of the column in BMM.
Thanks
You might get some clues by looking at the SQL generated by the BI Server. I can't see any issues with your column expression, so I wouldn't limit your debugging to that alone.
A query returning nulls is often caused by incorrect levels being set (especially on logical table sources, but potentially on a measure column too). This will often result in some form of SELECT NULL FROM ... in the physical SQL.
Try this :
FILTER("source"."recordCount" USING "source"."snapshot_date" =
EVALUATE('TO_CHAR(%1, %2)', TIMESTAMPADD(SQL_TSI_DAY, -7, EVALUATE('TO_DATE(%1, %2)', TO_CHAR("source"."snapshot_date" , 'YYYYMMDD') , 'YYYYMMDD')) , 'YYYYMMDD'))

ApplySimple Formula for Current year in Microstrategy

I'd like to nkow how to extract the current year using an ApplySimple formula for an Oracle DB being used on microstrategy.
The formula I tried is :
ApplySimple("to_char(SYSTIMESTAMP,'Year')")
Even though this formula is a valid one - when I try using this formula to create an attribute , and display it in a report , I get no results( blank column )
What I'm essentially trying to do is compare this current year attribute to another year attribute and create afilter based on this.
Any help wll be much appreciated!
I wouldn't bother with ApplySimple at all, it can be done directly in a filter.
Qualify on the attribute form that you want to compare (presumably the Year ID), and then in the Operator section, change the dropdown from its default 'Value' to 'Custom'.
This allows you to use MicroStrategy's built-in functions in your qualification. The current year can be returned by putting:
Year(CurrentDate())
for your comparison.
Are you sure you want to compare the string "twenty fourteen"? Because, TO_CHAR(SYSTIMESTAMP,'year') would return that. Instead, you might need the YYYY format :
TO_CHAR(SYSTIMESTAMP,'YYYY')
But that is still a string.
You probably need NUMBER :
So, I would prefer, EXTRACT(YEAR FROM SYSTIMESTAMP) Because, this will return 2014 as NUMBER.
SQL> SELECT EXTRACT(YEAR FROM SYSTIMESTAMP) FROM DUAL;
EXTRACT(YEARFROMSYSTIMESTAMP)
-----------------------------
2014
Formula
If the attribute is NUMBER data type, you might need this formula :
ApplySimple("EXTRACT(YEAR FROM SYSTIMESTAMP)")

Resources