ORACLE 11g SQL date query not returning data for today - oracle

I have the following SQL which should return all data up to 6.30am tomorrow. It has been working correctly until today (30/6/2016).
SELECT TO_CHAR(TRUK.THEDATE,'DD/MM/YY HH24:MI') DAT
FROM TRUK
WHERE TO_CHAR(TRUK.THEDATE,'DD/MM/YY HH24:MI') <= TO_CHAR(TO_DATE(sysdate + 1) + 6.5/24,'DD/MM/YY HH24:MI')
ORDER BY TRUK.THEDATE
PROBLEM
Today the data returned does not include data for 30th June,which i know exists but only 1st July. When i comment out the where clause, then all data is returned but of course this includes data AFTER 6.30am for the next day which i don't want returned.
I have searched in vain for an answer and would greatly appreciate some assistance with this. How Could the where clause be written differently to prevent this?
My desired result is that all records in the database are returned up to 6.30am the following day.
cheers

You're comparing strings, but you should be comparing dates.
Adjust your where clause to this and it'll work:
WHERE truk.thedate <= trunc(sysdate) + to_dsinterval('1 06:30:00')

Related

Query not filtering with date in Oracle

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

Obtaining a list of date to control file import

I have a need to pull in via FTP only files from dates I haven't pulled data. The data pulls happen nightly, but occasionally there is an issue and a night gets skipped, and it will be picked up the following night.
I located a query on StackOverflow which addressed most of my problem. However, I'm left with an uncomfortable solution and a lingering question.
I have a table with data from each file downloaded. The crux of the data I'm using for this example is EXTRACT_DATE. The file format is filename_20160809.csv, as an example. Uses the 4-digit year, 2-digit month and 2-digit day to make unique. The FTP location has thousands of files, and I only want to grab the new, based on this date.
First, I get the latest EXTRACT_DATE from my table as such
SELECT MAX(EXTRACT_DATE) INTO checkDate FROM FILE_DETAILS;
I had attempted to do this in a single query, but couldn't work it, and finally attempted to create a variable, checkDate, and use this variable in a subsequent query to obtain my list. However, having two queries in a single script is not allowed, or I haven't found a way to do it. So my primary issue is to return the value of the latest date. Then call a new query or procedure with the value incorporated in to obtain my list, with this query
SELECT TO_DATE(checkDate, 'MM/DD/YYYY') + rownum AS EXTRACT_DATES
FROM ALL_OBJECTS
WHERE TO_DATE(checkDate, 'MM/DD/YYYY') + rownum <= TO_DATE(SYSDATE, 'DD-MM-YY');
This solution is messy and uncomfortable, I would prefer a single query to get back my results, rather then 2 scripts or a script and a procedure.
The lingering question, the result from the query returns dates in the mm/dd/yyyy format; 8/9/2016. I adjusted the TO_DATE to match.
Initially, it was set to return as YYYY-MM-DD; 2016-08-09.
However, it wouldn't return in this format. It would only come back as 8/9/2016, regardless of the TO_DATE formatting used. I don't understand why the date is coming back in this format.
SELECT TO_DATE('2-AUG-2016', 'DD-MON-RR') + rownum AS EXTRACT_DATES
FROM ALL_OBJECTS
WHERE TO_DATE('2-AUG-2016', 'DD-MON-RR') + rownum <= TO_DATE(SYSDATE, 'DD-MM-YY');
EXTRACT_DATES
8/3/2016
8/4/2016
8/5/2016
8/6/2016
8/7/2016
8/8/2016
8/9/2016
NLS_DATE_FORMAT is set to DD-MON-RR, with American as NLS_DATE_LANGUAGE.

Select specific timestamp interval across multiple dates

I have tried searches on Google and various other sites with no luck, even making the search terms as vague as possible.
I have a query with data across multiple days but I only want to select data that has the time between 21:45 and 22:45.
The temp table built with the whole data has the data column that was converted from to_date to to_char so changing it back to to_date or to_timestamp is necessary, I think.
The problem is I have tried both of those and get invalid month errors. For example to_date(complete_date, 'hh24:mi:ss') gives me the error.
I'm not sure how to filter for a timestamp interval without giving a hard coded date.
Many thanks in advance. I am using Oracle Sql and unfortunately I don't have the query at the moment. It's on the computer at work. If a reply comes and I am at work I can reply back with more information.
With details as (
select to_char(complete_date, 'yyyy-mm-dd hh24:mi:ss') complete_date,
to_char(complete_date, 'hh24:mi:ss') as ts from table
where complete_date between trunc(sysdate)-30 and trunc(sysdate) )
select * from details where ts between '21:45:00' and '22:45:00'
I was able to filter by timestamp by using:
Round(Extract(hour from to_timestamp(complete_date, 'yyyy-mm-dd hh24:mi:ss')) + (extract(minute from to_timestamp(complete_date, 'yyyy-mm-dd hh24:mi:ss'))/60),2) count_ts
Then filter for count_ts between 21.75 and 22.75. This will allow me to get any data between those times no matter the day.
Problem solved.

SSRS 2005 passing datetime parameter to Oracle

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

complex sql query for finding the average working time of a person in office

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.

Resources