After running SELECT DISTINCT, duplicates still show - oracle

I am still seeing duplicates in my results after running the SELECT DISTINCT despite using all the appropriate techniques to insure duplicate rows are truly duplicate (applying trim to all fields, formatting the date fields as date only etc.). I even tried GROUP BY, yet after running it, duplicates still showed up. Does anyone have any clue what in the world is happening, and anything I can do?
SELECT DISTINCT
ID, Address_Line_1, Address_Line_2, City, State, Zip,
to_date(START_DATE, 'DD-MON-YYYY') as START_DATE,
to_date(END_DATE, 'DD-MON-YYYY') as END_DATE
FROM
AddressHistory
ORDER BY
ID, START_DATE DESC;

Try
SELECT DISTINCT
ID, Address_Line_1, Address_Line_2, City, State, Zip,
trunc(to_date(START_DATE, 'DD-MON-YYYY')) as START_DATE,
trunc(to_date(END_DATE, 'DD-MON-YYYY')) as END_DATE FROM
AddressHistory
ORDER BY ID, START_DATE DESC;
This truncates the times of the date and is faster than type cast conversion.
What data type is START_DATE in your example? Perhaps you can get rid of the type cast completely?

This is because the time factor in your column START_DATE and END_DATE is not the same, you should get distinct if you write your query like following.
SELECT DISTINCT * FROM
(
SELECT ID, Address_Line_1, Address_Line_2, City, State, Zip, to_date(START_DATE, 'DD-MON-YYYY') as START_DATE, to_date(END_DATE, 'DD-MON-YYYY') as END_DATE
FROM AddressHistory
)T
ORDER BY ID, START_DATE desc;

Related

How to write SELECT DISTINCT that works on DATE fields with time differences

Does anyone know how to write the SELECT DISTINCT statement so that the rows circled in blue can be treated as duplicates? Currently, at the date level, they are duplicates but they have time differences
SELECT ID, PHN_NO, DATE_CREATED, DATE_MODIFIED FROM USER_PHONE_HISTORY
WHERE PHONE_NUMBER = '1234567890'
ORDER BY START_DATE DESC;
-- 12 RECORDS
SELECT DISTINCT ID, PHN_NO, DATE_CREATED, DATE_MODIFIED FROM USER_PHONE_HISTORY
WHERE PHONE_NUMBER = '1234567890'
ORDER BY START_DATE DESC;
-- 12 RECORDS
If I understand correctly, you probably want something like
select distinct id, phn_no, trunc(date_created) as date_created,
trunc(date_modified) as date_modified
from user_phone_history
where .......
order by .......
or some simple modification thereof (it's not clear which date you must handle - this handles both).
I am not sure why you want to do this, but I assume you have your reasons...

Compare 2 date fields - when one date field is null

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

Oracle - select top transaction for each user_id

I have a select statement that gets user_id and a list of transactions for the day such as this:
select user_id, sale_amount, date, product from transactions
I want to be able to select each user_id (there are many) along with their top sale_amount, date and product. If there is a tie, I want it to just select one. How is this possible? Rownum or rank seem to be close but not quite there?
I m not ifo computer but this should work. Let me know
select * from (select user_id, sale_amount, date, product,row_number() over (partition by user_id order by sales_amount desc) as maxsale from transactions) l where maxsale=1

Change the data format

I use a script in oracle which select at a moment a date :
CURSOR SAURON IS select TOUTDOUX_ID, TYPE_OF_ACTION, USER_ID, PROFILE_NAME, START_DATE, END_DATE, PLATFORM, COMMENTS, PERM_FLAG, ACTIVE_FLAG from uam.tout_doux
But the format (25-JUL-2013) is not the one I expected (2013/07/25).
How can I select the date with the right format ?
Use the Oracle TO_CHAR function with date-time format elements. In your case you want the format string YYYY/MM/DD:
CURSOR SAURON IS
select TOUTDOUX_ID, TYPE_OF_ACTION, USER_ID, PROFILE_NAME,
TO_CHAR(START_DATE, 'YYYY/MM/DD') AS SDate,
TO_CHAR(END_DATE, 'YYYY/MM/DD') AS EDate,
PLATFORM, COMMENTS, PERM_FLAG, ACTIVE_FLAG
from uam.tout_doux

ORACLE: How to select previous different value?

I have table that stores employee job name, it has the following columns:
id; date_from; date_to; emp_id; jobname_id; grade;
Each emp_id can have many consecutive records with the same jobname_id due to many grade changes.
How can I select previous different jobname_id omitting those that are the same like the most current one?
This solution uses the FIRST_VALUE() analytic function to identify each employee's current job. It then filters for all the jobs which dfon't match that one:
select distinct id
, jobname_id
from ( select id
, jobname_id
, first_value(jobname_id) over (partition by id
order by from_date desc) as current_job
from employee
where emp_id = 1234 )
where jobname_id != current_job
order by id, jobname_id
/
Will this work for your issue:
SELECT DISTINCT
e1.emp_id,
e1.jobname_id
FROM employee e1
WHERE NOT EXISTS
(SELECT 1
FROM employee e2
WHERE e1.emp_id = e2.emp_id
AND SYSDATE BETWEEN e2.date_from
AND NVL(e2.date_to, SYSDATE + 1));
(This asumes your table is named "employee" and emp_id is the PK value).
It selects unique emp_id, jobname_id values where the emp_id, jobname_id values are not current.
EDIT: I agree with Chin Boon that fundamentally this is a design issue and perhaps that should be addressed rather than working around the problem.

Resources