I'm not sure if this is a question or more of an exploration of a possible bug or a question about a better way to do handle this.
I have a rollup report that uses the
select column1id, column2date
from table1
where to_char(column2date,'yyyy-iw') = to_char(to_date('2012-12-31','yyyy-mm-dd'),'yyyy-iw')
The line: to_char(to_date('2012-12-31','yyyy-mm-dd'),'yyyy-iw') is converting to 2012-01, wrapping back to the beginning of the year.
Digging a bit further I find that the date 2012-12-31 is neither included in week: 2012-52 nor is it included in 2013-01, and 2012-53 doesn't return any data either... so I'm at a loss of what's going on here.
https://forums.oracle.com/forums/thread.jspa?threadID=995899
Ravi Kumar wrote: you need to use IYYY in format.
BluShadow wrote: ... When it calculates the YYYY and IW these are independant of each other so it won't reduce the YYYY output to [2013] just because you have included IW in the format mask. It looks at components of the mask and not the whole thing in combination.
select to_char(to_date('2012-12-31','yyyy-mm-dd'),'iyyy-iw') from dual;
returns 2013-01.
I think your WHERE clause should be:
where to_char(column2date,'iyyy-iw') = to_char(to_date('2012-12-31','yyyy-mm-dd'),'iyyy-iw')
Related
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
I have staging table which contains date as string with format 'mm/dd/yy'. I have Oracle 11g procedure to convert the string to date format before loading into main table. I'm using to_date('03/20/34','mm/dd/rr') to convert into date format which is giving wrong output as 03/20/2034 whereas the correct date is 03/20/1934. Please help me out to get the correct output where my table contains dates from both centuries.
"I'm using to_date('03/20/34','mm/dd/rr') to convert into date format which is giving wrong output as 03/20/2034 whereas the correct date is 03/20/1934. "
RR was a hack Oracle introduced in the last Millennium as part of the fight to resolve the Y2K bug. The standard date mask YY defaults the century to the current century. But in 1999 it was more likely that 01/01/00 meant 01/01/2000 rather than 01/01/1900. So the RR hack was to derive the century for dates using fixed windows pivoting on 00: values 00-49 are given century 20, 50-99 are given 19. Clearly some of the time this guess would be wrong, but the data corruption introduced was of a lower level than defaulting all dates to century 19.
The key point is, the windows are fixed. It was intended to be a temporary solution, because there wasn't time to switch all the legacy systems to use four-digit years before 2000 arrived. But the vision was always that all systems would be fixed in the long term, even if only through retirement or replacement. Certainly nobody expected that new systems would be built supporting two-digit years.
It is now 2017 and there is no excuse for systems to still be using two-digit years. Back in the old days storage was expensive, and shaving two digits from a date was a valuable space saving. Now it is just sloppiness.
Which obviously doesn't help you solve your problem. The short answer is there is no way to change the pivot used by RR. The best solution would be to enforce stricter validation on the data input aspect of your system, and insist on four-digit years. Whether that's feasible depends on your office politics. The other solution is to write your own conversion function:
create or replace function my_to_date (p_str varchar2) return date as
begin
if to_number(substr(p_str, 7) <= 35 then
return to_date(substr(p_str, 1, 6)||'19'||substr(p_str, 7), 'dd/mm/yyyy');
else
return to_date(substr(p_str, 1, 6)||'20'||substr(p_str, 7), 'dd/mm/yyyy');
end;
Obviously you'll need to define the actual rules for deciding whether to use 19 or 20.
I also encountered an issue like this, when inserting date values from the late 90s. The format in the script I was given read DD-MON-YY, so the database read that as 20YY, instead of 19YY.
My very inelegant solution was to open the raw data file and simply add a "19" before the YY year values.
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'))
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)")
I recently came across sample code like this:
select TO_CHAR(DATE '2012-3-1', 'Day Month Year') from dual;
I understand the TO_CHAR, but I have never seen that use of DATE before, and can find no documentation relating to it. Can someone please explain how it works, and/or provide a link to some documentation?
Thanks,
Dan
You haven't searched far enough :-) Google Oracle DATE literal and find:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#BABGIGCJ
An extract:
To specify a DATE value as a literal, you must use the Gregorian
calendar. You can specify an ANSI literal, as shown in this example:
DATE '1998-12-25'
here's the doc: http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#BABGIGCJ