How do I get data between midnight today and NOW? - sql

As the title suggests, I'm simply trying to get the result set between midnight today and right now. So given the time of this post, I want data between 06/30/16 00:00:00 and 06/30/16 15:52:00. Why does the below query not return anything? Thanks.
SELECT * FROM tableName
WHERE event_date >= TO_DATE(TRUNC(SYSDATE) || ' 00:00:00', 'DD-MON-YY HH24:MI:SS')
AND event_date <= TO_DATE(TRUNC(SYSDATE))

SELECT *
FROM tableName
WHERE event_date BETWEEN TRUNC(SYSDATE) AND SYSDATE;

The solution was as follows:
SELECT * FROM tableName
WHERE event_date >= TO_DATE(TRUNC(SYSDATE))
I had forgotten that TRUNC(**SYSDATE)** by itself is perceived as midnight unless otherwise specified, so this does the trick.

Related

Oracle : Selecting date by month with where clause

I came across a problem that in selecting the date for current desired month and year. I tried the 2 statements shown below but failed to execute the query
select to_char(sysdate, 'Month') from income
select * from income where to_char(sysdate,month) = 'feb'
Update
But after researching and learning more in depth on oracle docs website. What i came out with is to use "between" clause. Specifying the first day and last day of the month . Doing so, it will execute the desired month/year
For an example
SELECT column_name
FROM table_name where column_name = (Your own value) AND
column_date >= to_date('01/02/2012', 'dd/mm/yyyy')
and column_date < to_date('01/03/2012', 'dd/mm/yyyy')
I hope this help :)
Are you after something like:
select *
from income
where <date_column> >= to_date('01/05/2019', 'dd/mm/yyyy')
and <date_column> < to_date('01/06/2019', 'dd/mm/yyyy')
(replacing <date_column> with the name of the date column in your income table that you want to filter on)?
I think you can use the following query:
select *
from income
where to_char(<date_column>,'MON-RRRR') = 'MAY-2019';
If you want to pass in a string like 'May 2012', then I would recommend:
select i.*
from income i
where i.datecol >= to_date('May 2012', 'Mon YYYY') and
i.datecol < to_date('May 2012', 'Mon YYYY') + interval '1' month;
That said, I think your application should turn the string value into a date range and you should use that range in your query:
select i.*
from income i
where i.datecol >= :datestart
i.datecol < :dateend + interval '1 day';
I strong encourage you to avoid between with dates, particularly in Oracle. The date data type has a built-in time component, and that can throw off the comparisons.

Oracle query on time (and not date)

How can you query on just the time portion of an Orace date field. Ie:
select * from mytable
where
date_column < '05:30:00'
Want the query to return any rows where the time represented by date_column is less than 5:30 regardless of the date.
You can try like this:
select * from mytable
where
to_char( date_column, 'HH24:MI:SS' ) < '05:30:00'
You can see how far the date is from midnight, and filter on that:
select * from mytable
where date_column - trunc(date_column) < 5.5/24
The date_column - trunc(date_column) calculation will give you a fraction of a day, as is normal for date arithmetic. The 5.5/24 is the fraction of the day represented by the time at 05:30; 5.5 hours out of 24 hours.
If the column was a timestamp instead of a date you'd see an interval data type as the result of the subtraction. You can use an interval literal anyway if you prefer or find it easier to understand than 5.5/24 (or have more complicated times to compare, which are harder to express as a fraction):
select * from mytable
where date_column < trunc(date_column) + interval '0 05:30:00' day to second;
This way round you're comparing the date in your column with the truncated date (i.e. midnight on that day) with 5 hours 30 minutes added to it, which is 05:30 the same day.
Quick demo with simple data in a CTE, and a third very slight variant, but they all get the same result:
with mytable (date_column) as (
select to_date('2016-04-15 05:29:29', 'YYYY-MM-DD HH24:MI:SS') from dual
union all select to_date('2016-04-14 05:29:29', 'YYYY-MM-DD HH24:MI:SS') from dual
union all select to_date('2016-04-15 05:30:30', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select * from mytable
where date_column < trunc(date_column) + 5.5/24;
DATE_COLUMN
-------------------
2016-04-15 05:29:29
2016-04-14 05:29:29
Note though that any manipulation of the column like this will prevent an index being used. If you have to do this regularly it might be worth adding a virtual column/index which does that calculation.
You need to cast the time back to date, otherwise you're simply doing string comparison.
Oracle doesn't really have a clever way of doing this. Simplest to cast both dates to the same day and do the comparison.
I.e.
select *
from mytable
where to_date ('01.01.2000 ' || to_char (date_column, 'hh24:mi:ss'), 'dd.mm.yyyy hh24:mi:ss') <
to_date ('01.01.2000' || '05:30:00', 'dd.mm.yyyy hh24:mi:ss')

Query not getting current date result

I am getting data from table for certain date range, but the query not getting data for today's date. Why does this happen?
select *
from mytable
where action_date >= to_date('01/07/2015', 'DD/MM/YYYY')
and action_date <= to_date('22/07/2015', 'DD/MM/YYYY');
Result is not showing 22/07/2015 data.
Edit:
ACTION_DATE TIMESTAMP(6)
Sample date in that column :
22/07/15 12:47:18.000000000 PM
Try to add the time part:
select *
from mytable
where action_date >= to_date('01/07/2015 00:00:00,000000000', 'DD/MM/YYYY HH24:MI:SS,FF9')
and action_date <= to_date('22/07/2015 23:59:00,999999999', 'DD/MM/YYYY HH24:MI:SS,FF9');
If you only give the date part, the time part is automatically added with the actual time, so if the time part is later you do not get the row.
to_date('22/07/2015', 'DD/MM/YYYY')
this will equal to July, 22 2015 00:00:00
From Oracle document:
Oracle Database stores time in 24-hour format—HH:MI:SS. By default,
the time in a date field is 00:00:00 A.M. (midnight) if no time
portion is entered.
so action_date <=/>= will compare the data+time.
For the correct result add required time to the date field.
eg:
to_date('22/07/2015 12:56', 'DD/MM/YYYY HH24:MI')
it is because you are converting to_date in date, that results in 22/2/2015 00:00:00 and your action_date time for 22/7/2015 is with some time appended. you need to convert action_date in date.
select * from mytable where cast( action_date >= to_date('01/07/2015', 'DD/MM/YYYY') and cast( action_date as date) <= to_date('22/07/2015', 'DD/MM/YYYY');
I have changed the query by this way, its working as expected.
SELECT *
FROM mytable
WHERE action_date >= to_date('01/07/2015', 'DD/MM/YYYY')
AND TRUNC(to_date(TO_CHAR(action_date, 'DD/MM/YYYY'), 'DD/MM/YYYY')) <= TRUNC(to_date('22/07/2015', 'DD/MM/YYYY'));
You can use the below query.
select *
from mytable
where trunc(action_date) >= to_date('01/07/2015', 'DD/MM/YYYY')
and trunc(action_date) <= to_date('22/07/2015', 'DD/MM/YYYY');
This will perform a date-level comparison rather than one based on the date and exact time.
This is better than the (original) accepted answer, which misses a small period of time after 23:59.
select *
from mytable
where action_date >= to_date('01/07/2015', 'DD/MM/YYYY')
and action_date < to_date('22/07/2015', 'DD/MM/YYYY') + 1;
Or alternatively if you don't like the +1:
select *
from mytable
where action_date >= to_date('01/07/2015', 'DD/MM/YYYY')
and action_date < to_date('23/07/2015', 'DD/MM/YYYY');
The easiest solution is to use '< nextday' instead of boring '<= 23:59:59'.
select * from mytable
where action_date >= to_date('01/07/2015', 'DD/MM/YYYY')
and action_date < to_date('23/07/2015', 'DD/MM/YYYY');

Insert date in oracle

When i executed the below query in Oracle
select TO_CHAR((CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS') from dual;
O/P : 04-Mar-2014 14:25:14
I would like to select current date only without current time as below
select TO_CHAR(trunc(CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS') from dual;
O/P : 04-Mar-2014 00:00:00
To achieve the only way is to apply function trunc() on the query? Is there any another way?
Edit : Thanks for your ans.Can it be done without any function?(wihout using to_char or trunc)
{sorry for missing this info}
The answer is simply no, there is no function that only gets the date part of the date / time (even current_date or sysdate are functions after all).
You should always use trunc to get the current date, without the time.
It isn't necessary to do a trunc and a to_char together. Keep to_char and don't specify the time part.
This is sufficient:
To get the date as varchar:
select TO_CHAR(CURRENT_DATE,'DD-Mon-YYYY') from dual
To get the date as date, with the time part as 00:00:00:
select trunc(CURRENT_DATE) from dual
You can do this:
select TO_CHAR(CURRENT_DATE,'DD-Mon-YYYY')||' 00:00:00' from dual;
there is also EXTRACT function which can be used like that:
SELECT extract(DAY FROM sysdate)
||'-' ||
extract(MONTH FROM sysdate)
|| '-' || extract(YEAR FROM sysdate)
FROM dual;
result: 4-3-2014
Use This Query...
select (TO_CHAR(TRUNC(CURRENT_DATE),'DD-Mon-YYYY HH24:MI:SS')) from dual

Oracle date function for the previous month

I have the query below where the date is hard-coded. My objective is to remove the harcoded date; the query should pull the data for the previous month when it runs.
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and TRUNC(CREATION_DATE) BETWEEN '01-AUG-2012' AND '31-AUG-2012'
Should I use sysdate-15 function for that?
Modifying Ben's query little bit,
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
The trunc() function truncates a date to the specified time period; so trunc(sysdate,'mm') would return the beginning of the current month. You can then use the add_months() function to get the beginning of the previous month, something like this:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and creation_date >= add_months(trunc(sysdate,'mm'),-1)
and creation_date < trunc(sysdate, 'mm')
As a little side not you're not explicitly converting to a date in your original query. Always do this, either using a date literal, e.g. DATE 2012-08-31, or the to_date() function, for example to_date('2012-08-31','YYYY-MM-DD'). If you don't then you are bound to get this wrong at some point.
You would not use sysdate - 15 as this would provide the date 15 days before the current date, which does not seem to be what you are after. It would also include a time component as you are not using trunc().
Just as a little demonstration of what trunc(<date>,'mm') does:
select sysdate
, case when trunc(sysdate,'mm') > to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as gt
, case when trunc(sysdate,'mm') < to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as lt
, case when trunc(sysdate,'mm') = to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as eq
from dual
;
SYSDATE GT LT EQ
----------------- ---------- ---------- ----------
20120911 19:58:51 1
Data for last month-
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where dealer_name = 'XXXX'
and to_char(CREATION_DATE,'MMYYYY') = to_char(add_months(trunc(sysdate),-1),'MMYYYY');
I believe this would also work:
select count(distinct switch_id)
from xx_new.xx_cti_call_details#appsread.prd.com
where
dealer_name = 'XXXX'
and (creation_date BETWEEN add_months(trunc(sysdate,'mm'),-1) and trunc(sysdate, 'mm'))
It has the advantage of using BETWEEN which is the way the OP used his date selection criteria.
It is working with me in Oracle sql developer
SELECT add_months(trunc(sysdate,'mm'), -1),
last_day(add_months(trunc(sysdate,'mm'), -1))
FROM dual
Getting last nth months data retrieve
SELECT * FROM TABLE_NAME
WHERE DATE_COLUMN BETWEEN '&STARTDATE' AND '&ENDDATE';