I have a requirement to create two validations on the date prompt:
1) The From Date has to be less than To Date
2) The To Date has to be less than or equal to current date
I created a conditional analysis wherein From Date is < To Date, which works, but when I try to create an advanced filter wherein #To_Date <= Current_Date I am getting an error.
Error getting drill information: SELECT date'2016-08-24' saw_0 FROM "Workforce Management - Processed Time Cards Real Time" WHERE(date'#{To_Date}' <= (SELECT VALUEOF("CURRENT_DATE_REP_OTBI") FROM "Workforce Management - Processed Time Cards Real Time" FETCH FIRST 1 ROWS ONLY))
If anyone can help solve this, it'd be really helpful!
Thanks
You need to add a default value when referencing presentation variables in logical SQL queries or formulas. Especially if these are dates.
I created an analysis based on the following LogicalSQL and it worked.
SELECT date'2016-08-26' saw_0 from "subject_area" WHERE (date
#{to_date}{'2016-08-26'} < CURRENT_DATE)
Notice the following:
The presentation variable #{to_date} goes with a default value (noted by the second curly brackets). This helps OBIEE to validate the query. Failing to add the default value will give you the "getting drill information" error.
Instead of a session RPD variable, you can use CURRENT_DATE. It simplifies the query.
The above query will return the date in the SELECT clause, but if the to_date is greater than CURRENT_DATE will return no data.
Related
My Datedim function is not returning yesterdays date in webi, any ideas on how to show 13/04/2022, even if it has null values?
Thanks
If you have gaps in your date data the simplest way to fill them in is to create a variable with the TimeDim() function. However, that will not work for you since you do not have a true gap because your missing date is at the end.
You need a data source with all the dates you want to display regardless of if you have data for those dates or not and then merge on your date dimension. I answered a question very similar to this here. I am copying my answer from there below...
The TimeDim() function will fill in the empty periods in your time
data. The problem with that though is if it is the end of your date
range that is missing data those dates will not show up. Let me show
you what I mean. Here is my sample data from 12/01/2021 through
12/26/2021 (note missing dates) in the table on the left. The table on
the right is the my Var Data Date TimeDim variable defined as…
=TimeDim([Data Date]; DayPeriod)
So we have our missing dates in the middle, but not at the end
(12/25/2021 and 12/26/2021). To get those dates you need a query to
return all the dates in your specified range. If you have a universe
based on a
calendar
you could use that. Free-hand SQL based on a calendar table would
suffice as well.
If you have neither of those we can still get it to work using
free-hand SQL with a CTE. This is SQL Server syntax. You will have to
modify this SQL to work for whatever database platform you have if it
isn’t SQL Server.
Here is the SQL…
;with dates ([Date]) as (
Select convert(date,‘2021-12-01’) as [Date] – Put the start date here
union all
Select dateadd(day, 1, [Date])
from dates
where [Date] < ‘2021-12-26’ – Put the end date here
)
select [Date]
from dates
option (maxrecursion 32767) – Don’t forget to use the maxrecursion option!
Source: Generate a Date Table via Common Table Expression (CTE) |
Data and Analytics with Dustin
Ryan
Here is a
demo.
Now that you have a query returning all of the dates in your range
you can merge the date from that query to your Data Date.
You can then put the date object with all of dates or the Merged Date
in table with any measures from your pre-existing query and there you
have it.
If you need to add dimensions from you pre-existing query I think you
will need to create variables for them with Qualification set to
“Detail” and the Associated dimension set to “Merged Date” (or
whatever you called it). And if you do that I believe you will also
need to check “Avoid duplicate row aggregation” check box within the
Format Table properties.
Let us know how it goes.
Hopefully that will get you on the right track.
There are records in table for particular date. But when I query with that value, I am unable to filter the records.
select * from TBL_IPCOLO_BILLING_MST
where LAST_UPDATED_DATE = '03-09-21';
The dates are in dd-mm-yy format.
To the answer by Valeriia Sharak, I would just add a few things since your question is tagged Oracle. I was going to add this as a comment to her answer, but it's too long.
First, it is bad practice to compare dates to strings. Your query, for example, would not even execute for me -- it would end with ORA-01843: not a valid month. That is because Oracle must do an implicit type conversion to convert your string "03-09-21" to a date and it uses the current NLS_DATE_FORMAT setting to do that (which in my system happens to be DD-MON-YYYY).
Second, as was pointed out, your comparison is probably not matching rows due LAST_UPDATED_DATE having hours, minutes, and seconds. But a more performant solution for that might be:
...
WHERE last_update_date >= TO_DATE('03-09-21','DD-MM-YY')
AND last_update_date < TO_DATE('04-09-21','DD-MM-YY')
This makes the comparison without wrapping last_update_date in a TRUNC() function. This could perform better in either of the following circumstances:
If there is an index on last_update_date that would be useful in your query
If the table with last_update_date is large and is being joined to other tables (because it makes it easier for Oracle to estimate the number of rows from your table that are inputs to the join).
Your column might contain hours and seconds, but they can be hidden.
So when you filter on the date, oracle implicitly adds time to the date. So basically you are filtering on '03-09-21 00:00:00'
Try to trunc your column:
select * from TBL_IPCOLO_BILLING_MST
where trunc(LAST_UPDATED_DATE) = '03-09-21';
Hope, I understood your question correctly.
Oracle docs
I have a SSRS 2005 report runs on a Oracle 9 database.
The report use this simple query to return a dataset
SELECT order_number FROM apps.oe_order_headers_all
WHERE ordered_date >= to_date(:start_date,'DD-MON-YYYY')
AND ordered_date < to_date(:end_date,'DD-MON-YYYY') +1
The parameters work fine if they are of type string in SSRS. E.g. 01-JAN-2014 for both start_date and end_date. But if changed to datetime the report returns nothing (if in string, the report returns many rows). I really want to use the date picker control of SSRS.
This is probably more of a SSRS thing than Oracle thing?
This is probably a date conversion issue, but I'm surprised it isn't either erroring, or returning the same data - at least for the example date you gave.
In your previous question you were entering a string, so adding the to_date() made sense. But if you're binding it as a date then you do not want those.
This is fine:
to_date(<string>,'DD-MON-YYYY')
But this:
to_date(<date>,'DD-MON-YYYY')
is really doing:
to_date(to_char(<date>,<NLS_DATE_FORMAT>), 'DD-MON-YYYY')
If your `NLS_DATE_FORMAT happens to be the same as the fixed format you supplied, then this is kind of OK as it's just a redundant conversion to a string and back. But if they are different then you'll get errors or incorrect results.
For example, if my NLS_DATE_FORMAT is MM/DD/YYYY' thento_date(sysdate, 'DD-MON-YYYY) gets anORA-01843: not a valid montherror, because it's trying to interpret28as the month and02` as the day.
So you just need to simplify it to:
SELECT order_number FROM apps.oe_order_headers_all
WHERE ordered_date >= :start_date
AND ordered_date < :end_date +1
Given the odd error you get from this, you could also try:
AND ordered_date < :end_date + interval '1' day
... but without understanding why the simpler +1 is erroring I'm not confident that will help. It doesn't seem to be following the normal datetime arithmetic rules. This is another possibility but should not be necessary:
AND ordered_date < CAST(:end_date AS DATE) + 1
We have a situation, where we have a table (say Forms) in Oracle DB which has a column (say edition_date) of type date. It was strictly meant to hold the date information in YYYY-MM-DD (ex: 2012-11-23)format with no timestamp value.
Unfortunately, due to a code problem, lot of rows got created with timestamp values. There are tons of records in this table, and I want to update only those rows which had this bad data. I can do that using the query
UPDATE forms SET edition_date = TRUNC( edition_date )
I want to add a where clause to it, so it updates only the bad data. The problem, I am not sure how to retrieve those rows that has timestamp added to it. Below is a snapshot of the data I have:
FORM_ID EDITION_DATE
5 2012-11-23
6 2012-11-23 11:00:15
..
11 2010-07-11 15:23:22
..
13 2011-12-31
I want to retrieve only the row with form ids 6 and 11. I trioed using the length functions but I think that is good for Strings only. Is there any way to do this. Thanks anyone who can help me.
A date has no format; you're only seeing how it's displayed. However, the answer to your question is, effectively, what you've said:
I want to add a where clause to it, so it updates only the bad data.
So, where the date is not equal to the date without time:
update forms
set edition_date = trunc(edition_date)
where edition_date <> trunc(edition_date)
To ensure that this doesn't happen again you can add a check constraint to your table:
alter table forms
add constraint chk_forms_edition_date
check ( edition_date = trunc(edition_date) );
I would advise against all of the above. Don't destroy potentially useful data. You should simply select trunc(edition_date) where you do not want time. You may want to use the time in the future.
You're correct, do not use LENGTH() etc for dates, it depends on your NLS_DATE_FORMAT settings and so could be different on a session-by-session basis. Always use date functions when dealing with dates.
I need to retrieve using an oracle based query the working time of an employee which is the time coming in and time going out for an employee based on his transactions in the transaction table.
The transaction table has a date-time field which can be used for this purpose.
The steps involved would be as follows:
1) find the first transaction on a date and the last transaction on the same date - that would be his time in and timeout for that date
2) calculate the overall time-in as the avg of all time-ins on each date, similarly do for time-out
Transaction table is as follows: transctn(transid, resourceid, event, currentdate)
The second requirement is to find the average transactions performed each day, which is basically find the count of transids for each day and then average of that.
The final answer should be, when a userid is provided the query the return result is:
frequent working time(based on average): 9:43 am - 6:45 pm
average transactions performed/day = 43
How do I write the above requirement in oracle SQL or more smartly using Hibernate if Transctn is my Domain class
I have something like this:
select 'frequent working time: '
||(select rtrim(to_char(min(currentdate),'hh:mi pm')) from transctn)
||' - '||(select rtrim(to_char(max(currentdate),'hh:mi pm')) from transctn)
||', average transactions performed/day = '
||(select rtrim(to_char(count(distinct transid)/
count(distinct(to_char(currentdate,'rrmmdd')))) from transctn)
from dual
Firstly, your query has lots of selects from the same table stuck together, which isn't efficient, and makes it harder to read than necessary. And the rtrim isn't doing anything as you've already dictated the format. What you have can be rewritten as:
select 'frequent working time: '|| to_char(min(currentdate),'hh:mi pm')
||' - '|| to_char(max(currentdate),'hh:mi pm'),
'average transactions performed/day = '
|| to_char(count(distinct transid)
/count(distinct to_char(currentdate,'rrmmdd')))
from transctn;
But this isn't averaging properly, and isn't for a specific user. I'm join to assume this is homework and in the usual spirit of the site, try to give you pointers rather than the complete answer...
1) find the first transaction on a date and the last transaction on
the same date - that would be his time in and timeout for that date
You're not far off here, but you're breaking down by date. To get the time-in and time-out for every user, for each day, you could use:
select resourceid, trunc(currentdate), min(currentdate), max(currentdate)
from transctn
group by resourceid, trunc(currentdate)
order by resourceid, trunc(currentdate);
2) calculate the overall time-in as the avg of all time-ins on each
date, similarly do for time-out
You can't average dates directly in Oracle; you'd get ORA-00932: inconsistent datatypes: expected NUMBER got DATE. There are various ways to achieve the effect, you just need to figure out a safe way to treat the date - or more specifically here the time part - as a number. For example, you could treat the time portion as the difference between the actual time and the start of the day, which Oracle returns as a number:
select avg(min(currentdate) - trunc(currentdate)),
avg(max(currentdate) - trunc(currentdate))
from transctn
group by trunc(currentdate);
But you than have to translate that fractional number back into something recognisable. One way of doing that is to add the number to an arbitrary fixed date, and then just extract the time part as a string as you were already doing:
select to_char(date '2000-01-01' + avg(min(currentdate) - trunc(currentdate)),
'HH:MI pm') as avg_time_in,
to_char(date '2000-01-01' + avg(max(currentdate) - trunc(currentdate)),
'HH:MI pm') as avg_time_out
from transctn
group by trunc(currentdate);
This look messy and you might find a better way to do it. If it is homework then I would assume you've been taught methods for doing this sort of thing, or something that can be adapted to be applicable.
This is still for all resources, so you'll need to add a filter to restrict to one user ID. Hopefully this gives you some ideas for tackling the second requirement as well.