Finding the age of an event in Oracle - oracle

I have a table of sales with an ordered column as a timestamp type.
I would like to find the number of days since the last order. I though it should be simple.
I have tried various methods, but I can’t get a meaningful answer:
select max(ordered) from sales; -- 2022-05-17 22:47:24.467000
select sysdate-max(ordered) from sales; -- Unknown column type: 10
select current_time_stamp-max(ordered) from sales; -- Unknown column type: 10
I want to use the result in a CTE to then add to some other dates, so I thought it should at least result in either an interval type or a number of days.
How can I get the age of the above date?

There are 2 common options:
cast timestamp to date and use sysdate - cast(max(...) as date) - in this case you'll get a number in days:
SQL> select sysdate - cast(timestamp'2000-01-01 00:00:00' as date) diff1 from dual;
DIFF1
----------
8290.97766
use systimestamp - max(...) - in this case you'll get an Interval Day to Second:
SQL> select systimestamp - timestamp'2000-01-01 00:00:00' from dual;
SYSTIMESTAMP-TIMESTAMP'2000-01-0100:00:00'
------------------------------------------
+000008291 00:27:19.105859000

Related

Charts in Oracle Apex

Hi everyone I wanna ask u about how I can bring data last 24 hours into bar charts, is there any methods to make it please
I have this table without data
datetime
clientchannel
servicename
service_count
13_02_2022 9:35
*****
notification
2
It is a WHERE clause you need, I presume. Something like this:
select ...
from your_table
where datetime >= sysdate - 1;
Why? Because - when you subtract a number from DATE datatype value in Oracle - it subtracts that many days.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select sysdate right_now,
2 sysdate - 1 yesterday
3 from dual;
RIGHT_NOW YESTERDAY
------------------- -------------------
13.02.2022 11:01:34 12.02.2022 11:01:34
SQL>
If you store date values as strings (which means that DATETIME column is declared as e.g. VARCHAR2(20), and that's really bad idea), then you first have to convert it to a valid date datatype value - use TO_DATE function with appropriate format mask:
where to_date(datetime, 'dd_mm_yyyy hh24:mi') >= sysdate - 1
[EDIT] If you want to go 60 minutes back, then subtract that many minutes:
SQL> select sysdate right_now,
2 sysdate - interval '60' minute an_hour_ago
3 from dual;
RIGHT_NOW AN_HOUR_AGO
------------------- -------------------
14.02.2022 07:09:30 14.02.2022 06:09:30
SQL>

PL SQL data is in numeric format (20211023) i want to use the where clause on date column +30days

Select * from Table where date >='20210911' + 30days
the date is in numeric format and what to pull the records for a specific date +30days of specific date
Could you please help
Uh. Never store dates into any other datatype column but DATE. Now you first have to "convert" it, then do the arithmetic.
select *
from some_table
where to_date(date_column, 'yyyymmdd') > date '2021-09-11' + 30
--------
apply format mask that matches data in that column
Hope (should I say pray?) that all values represent valid dates. Nobody prevents you to store e.g. 20228579 into it, and - applying to_date to it - results in
SQL> select to_date('20228579', 'yyyymmdd') from dual;
select to_date('20228579', 'yyyymmdd') from dual
*
ERROR at line 1:
ORA-01843: not a valid month
SQL>
Once again, bad, BAD idea!
how to apply between clause ( where date_column between date '2021-09-11' and date '2021-09-11'+30
If you have an index on the column that you want to use then convert the value to a date then add 30 days to it and convert it back to a number:
SELECT *
FROM Table_Name
WHERE date_number BETWEEN 20210911
AND TO_NUMBER(
TO_CHAR(
TO_DATE(20210911, 'YYYYMMDD')
+ INTERVAL '30' DAY,
'YYYYMMDD'
)
)
If you don't have an index and want a simpler query then:
SELECT *
FROM Table_Name
WHERE TO_DATE(date_number, 'YYYYMMDD') BETWEEN DATE '2021-09-11'
AND DATE '2021-09-11' + INTERVAL '30' DAY
The best solution would be to convert your numeric column to a DATE column:
ALTER TABLE table_name ADD date_column DATE;
UPDATE table_name SET date_column = TO_DATE(date_number, 'YYYYMMDD');
ALTER TABLE table_name DROP COLUMN date_number;
Then:
SELECT *
FROM Table_Name
WHERE date_column BETWEEN DATE '2021-09-11'
AND DATE '2021-09-11' + INTERVAL '30' DAY
db<>fiddle here

Error: ORA-01848: day of year must be between 1 and 365 (366 for leap year) while extracting month and year from DateColumn(varchar(10))

SELECT TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'YYYY-MM') as Date_y FROM Table_d
Even want to get quarter from the same date which is again giving me the error ORA-01848 like
SELECT (CASE WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('01','02','03') THEN 'Q1'
WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('04','05','06') THEN 'Q2'
WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('07','08','09') THEN 'Q3'
ELSE 'Q4' END as QTR
FROM Table_d
The way I see it, nothing of what you posted returns ORA-01848. It is - usually, if not always - related to the DDD date format mask which represents day number within the year.
For example, this is correct, as day number 001 equals the 1st of January:
SQL> select to_date('001-2020', 'ddd-yyyy') from dual;
TO_DATE('0
----------
01.01.2020
This returns ORA-01848 as there's no day 405 in this (nor any) year:
SQL> select to_date('405-2020', 'ddd-yyyy') from dual;
select to_date('405-2020', 'ddd-yyyy') from dual
*
ERROR at line 1:
ORA-01848: day of year must be between 1 and 365 (366 for leap year)
So: if you're doing anything like this, make sure that stored values are correct; I presume that not all of them are.
Besides, that's what happens when people store dates as strings into VARCHAR2 (instead of DATE datatype) columns. I'm not saying that you're the cause, but you certainly are a victim here.
[EDIT]
Julian date, eh? In a comment, you said that you used such a query:
Select TO_CHAR(TO_DATE(Julian_dateColumn+1900000, 'YYDDD'), 'YYDDD'), 'DD/MM/YYYY') as column_d from sometable
I doubt it as it is invalid (I suppose you have superfluous , 'YYDDD')).
Anyway, I have no idea why you tried to "convert" Julian date in such a manner. There's a simple and correct way to do so. Here's how:
This is today's date (21.05.2020) presented as Julian date:
SQL> select to_char(sysdate, 'j') julian from dual;
JULIAN
-------
2458991
That's kind of values you have stored in the table. In order to convert it to format you wanted (yyddd), you'd
SQL> select to_char(to_date(2458991, 'j'), 'yyddd') as column_d from dual;
COLUM
-----
20142
I suggest you use this instead of code you currently have, i.e.
SQL> create or replace view table_d as
2 select to_char(to_date(julian_datecolumn, 'j'), 'yyddd') as column_d
3 from sometable;
View created.
SQL> select * From table_d;
COLUM
-----
20142
SQL>

Use time in between in oracle for multiple date

Select *
from mytable
where paid_time Between to_date('00:00:00','HH24:MI:SS' ) and to_date('00:59:59','HH24:MI:SS')
and paid_date Between to_date('1/8/2016','DD/MM/RRRR') and
to_date('10/8/2016','DD/MM/RRRR');
Note :
1. I need perticular time period only for 10 days
Error :
1. data is there but returning Zero kindly help to solve this
You need to use the full date and time TO_DATE otherwise there is conflicting WHERE clauses'DD/MM/RRRR hh24:mi:ss'.
SELECT *
FROM mytable
WHERE paid_time BETWEEN TO_DATE('01/08/2016 00:00:00', 'DD/MM/RRRR hh24:mi:ss') AND TO_DATE('10/08/2016 00:59:59', 'DD/MM/RRRR hh24:mi:ss');
If paid_time is a string then your query will only work at all for certain NLS_DATE_FORMAT settings, due to the implicit conversion you are forcing:
alter session set nls_date_format = 'RRRR-MM-DD';
with mytable (paid_date, paid_time) as (
select date '2016-08-02', '00:01:02' from dual
)
Select *
from mytable
where paid_time Between to_date('00:00:00','HH24:MI:SS' ) and to_date('00:59:59','HH24:MI:SS')
and paid_date Between to_date('1/8/2016','DD/MM/RRRR') and
to_date('10/8/2016','DD/MM/RRRR');
no rows selected
alter session set nls_date_format = 'YYYY-MM-DD';
-- same query
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
alter session set nls_date_format = 'DD/MM/RRRR';
-- same query
ORA-01847: day of month must be between 1 and last day of month
... etc.
When you do to_date('00:00:59','HH24:MI:SS') the generated date defaults to the first of the current month, so when run today it will get a September date:
select to_char(to_date('00:00:59','HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(TO_DATE('00
-------------------
2016-09-01 00:00:59
You are then trying to compare your paid_time string with that date, which means the string is implicitly converted to a date using your NLS settings, e.g.:
alter session set nls_date_format = 'RRRR-MM-DD';
select to_char(to_date('00:01:02'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(TO_DATE('00
-------------------
2000-01-02 00:00:00
So your filter is really looking for rows where the time string, incorrectly converted to a date (exactly which date depends on your actual NLS setting, and many values will error whatever the setting), is in the first minute of the first day of the current month. Which is very unlikely to ever match anything.
If it is a string and is always formatted consistently then you can just compare as a string:
with mytable (paid_date, paid_time) as (
select date '2016-08-02', '00:01:02' from dual
)
Select *
from mytable
where paid_time Between '00:00:00' and '00:59:59'
and paid_date Between to_date('1/8/2016','DD/MM/RRRR') and
to_date('10/8/2016','DD/MM/RRRR');
PAID_DATE PAID_TIM
---------- --------
2016-08-02 00:01:02
As mentioned in comments Oracle's data datatype includes the time, so storing the date (at midnight, presumably) and the time in separate columns just adds complexity and inefficiency.

Fetching column values based on SYSDATE

I have a table wchih has 2 columns. The definition is
CREATE TABLE LOGGING_T
(
TSTAMP DATE,
LINE VARCHAR2(300)
)
TABLESPACE OPERATIONS
MONITORING
/
The colulmn TSTAMP has values like 30-NOV-11, 29-NOV-11 ... and so on. Now i am doing this query
select * from LOGGING_T where TSTAMP >= (SYSDATE - 1)
The current system date is 01-DEC-11. Ideally, the above statement should return records which has TSTAMP = 30-NOV-11 since i am doing SYSDATE-1 which would be 30-NOV-11. But it isn't fetching those records. Why?
However, if i do this query
select * from LOGGING_T where TSTAMP >= (SYSDATE - 2)
Then it fetches records who TSTAMP is 30-NOV-11. Am i doing something wrong in this simple date operation?
A DATE contains time of day as well as the date.
If SYSDATE was 2011-12-01 1:18:00 PM then SYSDATE-1 would be 2011-11-30 1:18:00 PM.
Are the rows you are expecting to find from November 30th before or after the time element?
If you don't care about the time, and only want to filter based on the date, you can use TRUNC():
select *
from LOGGING_T
where TRUNC(TSTAMP) >= TRUNC(SYSDATE - 1);
You'll may or may not want to make sure both sides of your comparison operator are TRUNC()ed because TRUNC() will just force the time element of the date to be midnight.
select to_char(trunc(sysdate), 'YYYY-MM-DD HH:MI:SS PM')
from dual;
NOW
----------------------
2011-12-01 12:00:00 AM
The value SYSDATE has the time component as well. Most probably the date in your database also has the time component.
Change your query to :
select * from LOGGING_T where TSTAMP >= TRUNC(SYSDATE - 1)
to see all records which were logged from 00:00 yesterday.
To see the actual timecomponents, use to char.
SQL> select sysdate from dual;
SYSDATE
---------
01-DEC-11
1* select to_char(sysdate,'DD-Mon-YYYY HH24:MI:SS') date1 from dual
SQL> /
DATE1
--------------------
01-Dec-2011 16:29:01

Resources