Compare 2 date fields - when one date field is null - oracle

I wanted to select the rows whose date is greater than last processed date.
The last processed date is in hist table.
select id
from table1
where to_date(last_updated_date,'MM/DD/YYYY HH24:MI:SS')
> select to_date(nvl(max(last_updated_date),sysdate),'MM/DD/YYYY HH24:MI:SS')
from table1_hist;
This return ORA-01843: not a valid month error.
I had manually inserted row in table1 as TO_DATE('09/26/2019 14:37:49', 'MM/DD/YYYY HH24:MI:SS') while in table1_hist there are no rows.
But when I query the table using sql developer for table1 I get the value appearing as '26-SEP-19'. last_updated_date is a date field.
I wanted to to get the id's from table1 after the last executed time.
Thanks

SYSDATE is a DATE value. Using TO_DATE() on a value which is already a DATE is useless.
Try
where last_updated_date >
(select MAX(NVL(last_updated_date, SYSDATE)) from table1_hist);

I will suggest using an analytical function as following:
SELECT
ID
FROM
(
SELECT
T.ID,
T.LAST_UPDATED_DATE,
MAX(TH.LAST_UPDATED_DATE) OVER() AS M_LAST_UPDATED_DATE
FROM
TABLE1 T
JOIN TABLE1_HIST TH ON ( T.ID = TH.ID )
-- i am guessing that this is the join condition or you can use your own conition here
)
WHERE
LAST_UPDATED_DATE > COALESCE(M_LAST_UPDATED_DATE, SYSDATE)
Cheers!!

First of all, you don't need any to_date conversion for comparison.
If table1_hist has at least one non-null value, then using
select t.id
from table1 t
where t.last_updated_date > ( select max(th.last_updated_date) from table1_hist th )
is enough, but all those values are null then use a query such as this :
select t.id
from table1 t
where t.last_updated_date >
(select nvl(max(th.last_updated_date),t.last_updated_date-1) from table1_hist th)
Demo

Related

Oracle SQL -- Finding count of rows that match date maximum in table

I am trying to use a query to return the count from rows such that the date of the rows matches the maximum date for that column in the table.
Oracle SQL: version 11.2:
The following syntax would seem to be correct (to me), and it compiles and runs. However, instead of returning JUST the count for the maximum, it returns several counts more or less like the "HAIVNG" clause wasn't there.
Select ourDate, Count(1) as OUR_COUNT
from schema1.table1
group by ourDate
HAVING ourDate = max(ourDate) ;
How can this be fixed, please?
You can use:
SELECT MAX(ourDate) AS ourDate,
COUNT(*) KEEP (DENSE_RANK LAST ORDER BY ourDate) AS ourCount
FROM schema1.table1
or:
SELECT ourDate,
COUNT(*) AS our_count
FROM (
SELECT ourDate,
RANK() OVER (ORDER BY ourDate DESC) AS rnk
FROM schema1.table1
)
WHERE rnk = 1
GROUP BY ourDate
Which, for the sample data:
CREATE TABLE table1 (ourDate) AS
SELECT SYSDATE FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
SELECT SYSDATE - 1 FROM DUAL;
Both output:
OURDATE
OUR_COUNT
2022-06-28 13:35:01
5
db<>fiddle here
I don't know if I understand what you want. Try this:
Select x.ourDate, Count(1) as OUR_COUNT
from schema1.table1 x
where x.ourDate = (select max(y.ourDate) from schema1.table1 y)
group by x.ourDate
One option is to use a subquery which fetches maximum date:
select ourdate, count(*)
from table1
where ourdate = (select max(ourdate)
from table1)
group by ourdate;
Or, a more modern approach (if your database version supports it; 11g doesn't, though):
select ourdate, count(*)
from table1
group by ourdate
order by ourdate desc
fetch first 1 rows only;
You can use this SQL query:
select MAX(ourDate),COUNT(1) as OUR_COUNT
from schema1.table1
where ourDate = (select MAX(ourDate) from schema1.table1)
group by ourDate;

How to load the values of three column from one table1 to another table 2 which is having single column in hive?

Could you please help me below query.
Table 1 (Input)had three columns (Credit_date, Debit_date, Payment_date) and
Table 2 (Output) has one column date
The three column values from Table 1 should be available in Table 2.
I tried below query but not working.
insert into table2
select date
from (
(select credit_date, debit_date, Payment_date from table 1) as date)t;
Could you please guide.
Try doing a union all:
insert into table2
select * from (
select credit_date as date from table1
union all
select debit_date as date from table1
union all
select payment_date as date from table1
) t

Query taking long when i use user defined function with order by in oracle select

I have a function, which will get greatest of three dates from the table.
create or replace FUNCTION fn_max_date_val(
pi_user_id IN number)
RETURN DATE
IS
l_modified_dt DATE;
l_mod1_dt DATE;
l_mod2_dt DATE;
ret_user_id DATE;
BEGIN
SELECT MAX(last_modified_dt)
INTO l_modified_dt
FROM table1
WHERE id = pi_user_id;
-- this table contains a million records
SELECT nvl(MAX(last_modified_ts),sysdate-90)
INTO l_mod1_dt
FROM table2
WHERE table2_id=pi_user_id;
-- this table contains clob data, 800 000 records, the table 3 does not have user_id and has to fetched from table 2, as shown below
SELECT nvl(MAX(last_modified_dt),sysdate-90)
INTO l_mod2_dt
FROM table3
WHERE table2_id IN
(SELECT id FROM table2 WHERE table2_id=pi_user_id
);
execute immediate 'select greatest('''||l_modified_dt||''','''||l_mod1_dt||''','''||l_mod2_dt||''') from dual' into ret_user_id;
RETURN ret_user_id;
EXCEPTION
WHEN OTHERS THEN
return SYSDATE;
END;
this function works perfectly fine and executes within a second.
-- random user_id , just to test the functionality
SELECT fn_max_date_val(100) as max_date FROM DUAL
MAX_DATE
--------
27-02-14
For reference purpose i have used the table name as table1,table2 and table3 but my business case is similar to what i stated below.
I need to get the details of the table1 along with the highest modified date among the three tables.
I did something like this.
SELECT a.id,a.name,a.value,fn_max_date_val(id) as max_date
FROM table1 a where status_id ='Active';
The above query execute perfectly fine and got result in millisecods. But the problem came when i tried to use order by.
SELECT a.id,a.name,a.value,a.status_id,last_modified_dt,fn_max_date_val(id) as max_date
FROM table1 where status_id ='Active' a
order by status_id desc,last_modified_dt desc ;
-- It took almost 300 seconds to complete
I tried using index also all the values of the status_id and last_modified, but no luck. Can this be done in a right way?
How about if your query is like this?
select a.*, fn_max_date_val(id) as max_date
from
(SELECT a.id,a.name,a.value,a.status_id,last_modified_dt
FROM table1 where status_id ='Active' a
order by status_id desc,last_modified_dt desc) a;
What if you don't use the function and do something like this:
SELECT a.id,a.name,a.value,a.status_id,last_modified_dt x.max_date
FROM table1 a
(
select max(max_date) as max_date
from (
SELECT MAX(last_modified_dt) as max_date
FROM table1 t1
WHERE t1.id = a.id
union
SELECT nvl(MAX(last_modified_ts),sysdate-90) as max_date
FROM table2 t2
WHERE t2.table2_id=a.id
...
) y
) x
where a.status_id ='Active'
order by status_id desc,last_modified_dt desc;
Syntax might contain errors, but something like that + the third table in the derived table too.

Oracle select most recent date record

I am trying to find the most recent record based on a date field. When I set latest = 1 in the where clause, I get an error. Please help if possible. DATE is a the field I'm sorting by. I have tried both latest = 1 and latest = '1'
SELECT
STAFF_ID,
SITE_ID,
PAY_LEVEL,
ROW_NUMBER() OVER (PARTITION BY STAFF_ID ORDER BY DATE DESC) latest
FROM OWNER.TABLE
WHERE END_ENROLLMENT_DATE is null
AND latest = 1
you can't use aliases from select list inside the WHERE clause (because of the Order of Evaluation of a SELECT statement)
also you cannot use OVER clause inside WHERE clause - "You can specify analytic functions with this clause in the select list or ORDER BY clause." (citation from docs.oracle.com)
select *
from (select
staff_id, site_id, pay_level, date,
max(date) over (partition by staff_id) max_date
from owner.table
where end_enrollment_date is null
)
where date = max_date
Assuming staff_id + date form a uk, this is another method:
SELECT STAFF_ID, SITE_ID, PAY_LEVEL
FROM TABLE t
WHERE END_ENROLLMENT_DATE is null
AND DATE = (SELECT MAX(DATE)
FROM TABLE
WHERE staff_id = t.staff_id
AND DATE <= SYSDATE)
i think i'd try with MAX something like this:
SELECT staff_id, max( date ) from owner.table group by staff_id
then link in your other columns:
select staff_id, site_id, pay_level, latest
from owner.table,
( SELECT staff_id, max( date ) latest from owner.table group by staff_id ) m
where m.staff_id = staff_id
and m.latest = date
select *
from (select
staff_id, site_id, pay_level, date,
rank() over (partition by staff_id order by date desc) r
from owner.table
where end_enrollment_date is null
)
where r = 1

sql query: For each record where is_queue_empty=1 and queue_name is empty get immediate next record by timestamp where …

How can we construct sql query with following constraint.
For each record where is_queue_empty=1 and queue_name is empty get immediate next record by timestamp where is_queue_empty=0 and queue_name can or cannot be empty for same session-id and request-id.
Table has following columns:
session_id,request_id,queue_name ,is_queue_empty,timestamp,queue_tag,tab_name.
What I have do far is this which is incorrect:
SELECT x.tab_name,
x.is_queue_empty,
x.SESSION_ID,
x.request_ID,
x.TO_CHAR(DATETIME, 'YYYY/MM/DD HH24:MI:SS') timestamp,
y.tab_name,y.queue_name,y.is_queue_empty
FROM queue_data AS x
WHERE
timesttamp < TO_DATE('2011/02/30')
AND timestamp >= TO_DATE('2011/01/01')
AND is_queue_empty=1
AND timestamp < (select TO_CHAR(timestamp, 'YYYY/MM/DD HH24:MI:SS') as timestamp from queue_data as Y where x.session_id = y.session_id and x.request_id=y.request_id and y.is_queue_empty=0 order by y.timestamp asc limit 1 )
select a.session_id,a.request_id,a.timestamp,a.queue_tag,
b.*
from
(
select session_id,request_id,timestamp,queue_tag,
(select min(b.timestamp)
from tbl b
where a.session_id=b.session_id
and a.request_id=b.request_id
and b.timestamp > a.timestamp
and b.is_queue_empty=0) nextrec
from tbl a
where is_queue_empty=1 and nullif(queue_name,'') is null
) a
left join tbl b on a.session_id=b.session_id
and a.request_id=b.request_id
and a.nextrec = b.timestamp
Note:
tbl is the name of the table
Assuming timestamp is unique within a session_id,request_id combo

Resources