DATE queries using BETWEEN on oracle view - oracle

i have a problem with a date parameter query using 'between' operator in oracle view, when i do this query :
SELECT *
FROM MY_VIEW
WHERE STATUS = 'Active'
AND CHECKER_DATE BETWEEN to_date(sysdate - 1, 'DD-MON-YY') AND to_date(sysdate, 'DD-MON-YY');
it does not give me the records (actualy i have any record on that date).
I try using 'in' operator, but still not give me the records.
Please throw some information for this.
*checker_date defined as date

Your first error is to call to_date() on a value that is already a DATE. to_date() expects a VARCHAR value, so sysdate will be first converted to VARCHAR and will then immediately be converted back to a DATE value which it was to begin with.
You probably want
AND CHECKER_DATE BETWEEN trunc(sysdate) - 1 AND trunc(sysdate)
Most probably this will still not give you want you want as that would not include rows from "today". trunc(sysdate) means "today at midnight" and any row that was created today after midnight will not be included. With date/time values (and Oracle's DATE type does contain a time, despite the name) it's better to not use BETWEEN, but explicit range operators instead:
AND CHECKER_DATE >= trunc(sysdate) - 1
AND CHECKER_DATE < trunc(sysdate) + 1
trunc(sysdate) + 1 is tomorrow at midnight, so any value that is (strictly) smaller than that is "today".
All the above assumes that CHECKER_DATE is defined as DATE or TIMESTAMP

You can try:
SELECT *
FROM MY_VIEW
WHERE STATUS = 'Active'
AND CHECKER_DATE BETWEEN trunc(sysdate - 1) AND trunc(sysdate);
Oracle advises against using to_date for date. Also trunc is here because Trunc removes the time component.

may be records are not 'Active' or 'Active' a not-existing value in one of the reference tables if any and trunc(sysdate -1) and trunc(sysdate) would help

Related

Oracle SQL Developer get table rows older than n months

In Oracle SQL Developer, I have a table called t1 who have two columns col1 defined as NUMBER(19,0) and col2 defined as TIMESTAMP(3).
I have these rows
col1 col2
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
3 26/11/21 10:27:11,750000000
4 26/11/21 10:27:59,606000000
5 16/12/21 11:47:04,105000000
6 16/12/21 12:29:27,101000000
My sysdate looks like this:
select sysdate from dual;
SYSDATE
03/03/22
I want to create a stored procedure (SP) which will delete rows older than 2 months and displayed message n rows are deleted
But when i execute this statement
select * from t1 where to_date(TRUNC(col2), 'DD/MM/YY') < add_months(sysdate, -2);
I don't get the first 2 rows of my t1 table. I get more than 2 rows
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
How can i get these rows and deleted it please ?
In Oracle, a DATE data type is a binary data type consisting of 7 bytes (century, year-of-century, month, day, hour, minute and second). It ALWAYS has all of those components and it is NEVER stored with a particular formatting (such as DD/MM/RR).
Your client application (i.e. SQL Developer) may choose to DISPLAY the binary DATE value in a human readable manner by formatting it as DD/MM/RR but that is a function of the client application you are using and not the database.
When you show the entire value:
SELECT TO_CHAR(ADD_MONTHS(sysdate, -2), 'YYYY-MM-DD HH24:MI:SS') AS dt FROM DUAL;
Then it outputs (depending on time zone):
DT
2022-01-03 10:11:28
If you compare that to your values then you can see that 2022-01-03 12:00:00 is not "more than 2 months ago" so it will not be matched.
What you appear to want is not "more than 2 months ago" but "equal to or more than 2 months, ignoring the time component, ago"; which you can get using:
SELECT *
FROM t1
WHERE col2 < add_months(TRUNC(sysdate), -2) + INTERVAL '1' DAY;
or
SELECT *
FROM t1
WHERE TRUNC(col2) <= add_months(TRUNC(sysdate), -2);
(Note: the first query would use an index on col2 but the second query would not; it would require a function-based index on TRUNC(col2) instead.)
Also, don't use TO_DATE on a column that is already a DATE or TIMESTAMP data type. TO_DATE takes a string as the first argument and not a DATE or TIMESTAMP so Oracle will perform an implicit conversion using TO_CHAR and if the format models do not match then you will introduce errors (and since any user can set their own date format in their session parameters at any time then you may get errors for one user that are not present for other users and is very hard to debug).
db<>fiddle here
Perhaps just:
select *
from t1
where col2 < add_months(sysdate, -2);

How do I separate the time and date in SQL navigator?

I am trying to separate the time and date in one column to be independent off each other. I am new at writing scripts
this is my query:
select
*
from
[tablename]
where
to_date([column_name]) in ( '15-Jun-2021', '16-Jun-2021' )
and
to_char([column_name],'dd-Mon-yyyy HH:MM:ss') < '15-Jun-2021 19:54:30'
The way you put it, it would be
select *
from your_table
where date_column >= date '2021-06-15'
and date_column < to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss')
because
date_column should be of date datatype. If it isn't, you'll have problems of many kinds in the future. Therefore,
don't to_date it, it is already a date
don't to_char it either, because you'd be comparing strings and get unexpected result. Use that function when you want to nicely display the result
the second condition you wrote makes the first one questionable. If date_column is less than value you wrote, then you can omit date '2021-06-16' from the first condition because you won't get any rows for that date anyway
date literal (date '2021-06-15') sets time to midnight, so condition I wrote should return rows you want
SQL> select date '2021-06-15' first,
2 to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss') second
3 from dual;
FIRST SECOND
------------------- -------------------
15.06.2021 00:00:00 15.06.2021 19:54:30
SQL>

Oracle - trunc(DateTime) between trunc(Sysdate - 104) and trunc(Sysdate - 75)

I want to select few data from a Oracle table of June month(June 1st to June 30th of 2017) and the start date will be from tomorrow(Sep 13th). Hence I wrote a query in below format,
select * from table where column1='Data1' and Column2='Data2'
and trunc(DateTime) between trunc(sysdate-104) and trunc(sysdate-75)
I'm not able to check this query as I don't have tool for this. I just wrote it in notepad and want to share to my friend.
My Question - Will trunc(DateTime) between trunc(sysdate-104) and trunc(sysdate-75) condition will give data between June1st to June31 or Does any Syntax issue there?
There is no problem with the syntax itself even though your formulation is time sensitive, which means that tomorrow it won't return the same result.
Instead, go with something like this :
AND TRUNC(DateTime) BETWEEN to_date('2016-06-01','YYYY-MM-DD')
AND to_date('2016-06-30','YYYY-MM-DD')
Just cast the date format to month/year and compare against that.
select *
from table
where column1 = 'Data1'
and column2 = 'Data2'
and to_char(DateTime, 'MMYYYY') = '062017';
Hi I think the most accurate would be:
select * from table where column1='Data1' and Column2='Data2'
AND DateTime BETWEEN TRUNC(sysdate-104)
AND TRUNC(sysdate-75)
+ interval '23' hour
+ interval '59' minute
+ interval '59' second;

How to generate diff between TIMESTAMP and DATE in SELECT in oracle 10

I need to query 2 tables, one contains a TIMESTAMP(6) column, other contains a DATE column. I want to write a select statement that prints both values and diff between these two in third column.
SB_BATCH.B_CREATE_DT - timestamp
SB_MESSAGE.M_START_TIME - date
SELECT SB_BATCH.B_UID, SB_BATCH.B_CREATE_DT, SB_MESSAGE.M_START_TIME,
to_date(to_char(SB_BATCH.B_CREATE_DT), 'DD-MON-RR HH24:MI:SS') as time_in_minutes
FROM SB_BATCH, SB_MESSAGE
WHERE
SB_BATCH.B_UID = SB_MESSAGE.M_B_UID;
Result:
Error report -
SQL Error: ORA-01830: date format picture ends before converting entire input string
01830. 00000 - "date format picture ends before converting entire input string"
You can subtract two timestamps to get an INTERVAL DAY TO SECOND, from which you calculate how many minutes elapsed between the two timestamps. In order to convert SB_MESSAGE.M_START_TIME to a timestamp you can use CAST.
Note that I have also removed your implicit table join with an explicit INNER JOIN, moving the join condition to the ON clause.
SELECT t.B_UID,
t.B_CREATE_DT,
t.M_START_TIME,
EXTRACT(DAY FROM t.diff)*24*60 +
EXTRACT(HOUR FROM t.diff)*60 +
EXTRACT(MINUTE FROM t.diff) +
ROUND(EXTRACT(SECOND FROM t.diff) / 60.0) AS diff_in_minutes
FROM
(
SELECT SB_BATCH.B_UID,
SB_BATCH.B_CREATE_DT,
SB_MESSAGE.M_START_TIME,
SB_BATCH.B_CREATE_DT - CAST(SB_MESSAGE.M_START_TIME AS TIMESTAMP) AS diff
FROM SB_BATCH
INNER JOIN SB_MESSAGE
ON SB_BATCH.B_UID = SB_MESSAGE.M_B_UID
) t
Convert the timestamp to a date using cast(... as date). Then take the difference between the dates, which is a number - expressed in days, so if you want it in minutes, multiply by 24*60. Then round the result as needed. I made up a small example below to isolate just the steps needed to answer your question. (Note that your query has many other problems, for example you didn't actually take a difference of anything anywhere. If you need help with your query in general, please post it as a separate question.)
select ts, dt, round( (sysdate - cast(ts as date))*24*60, 2) as time_diff_in_minutes
from (select to_timestamp('2016-08-23 03:22:44.734000', 'yyyy-mm-dd hh24:mi:ss.ff') as ts,
sysdate as dt from dual )
;
TS DT TIME_DIFF_IN_MINUTES
-------------------------------- ------------------- --------------------
2016-08-23 03:22:44.734000000 2016-08-23 08:09:15 286.52

Date comparison in Oracle 11g

I'm new to Oracle 11g & I have a question about a query.
I have a table dummy which has created_date column of type Date.
I want a query which will return all the records where created_date + 7 days is less than today's date.
What type of query in Oracle 11g accomplishes this?
Oracle lets you use + for date arithmetic, so
where table.created_date >= sysdate
and table.created_date < sysdate + 7
will find rows between exactly now and exactly now plus 7 days.
If you don't want to include the time component, you can use the trunc() function
where trunc(table.created_date) >= trunc(sysdate)
and trunc(table.created_date) < trunc(sysdate) + 7
I think rejj's solution will give you the records between now and seven days in the future. From your description, it sounds like you probably want those records within the past seven days. I'd do this as:
WHERE created_date <= SYSDATE
AND created_date >= SYSDATE - 7
This may be more clear, and is equivalent:
WHERE created_date BETWEEN SYSDATE AND (SYSDATE - 7)
Be aware that using TRUNC() will cause the optimizer to bypass any indexes you have on created_date, unless you have a functional index defined.
Using INTERVAL constants can make date arithmetic clearer, as in
SELECT *
FROM DUMMY
WHERE CREATED_DATE >= TRUNC(SYSDATE) - INTERVAL '7' DAY
Share and enjoy.

Resources