Reputation: 21
There is an EMPLOYEE table as below
EPM_ID
------
1001
1002
1004
And I have a list of EPM_IDs which I want to validate: (1000, 1001, 1002, 1003, 1004, 1005)
How to write Oracle SQL query only (without creating any temporary table) to return list of EPM_IDs that are not in the EMPLOYEE table, but are in my list? For instance, the result should be 1000, 1003, 1005.
Upvotes: 0
Views: 1092
Reputation: 21
So, here is the solution which saved my day. I had restrictions to create temporary table in production DB which is a simple and obvious solution to solve this problem.
SELECT column_value AS EMP_ID
FROM TABLE(sys.Odcinumberlist(1000, 1001, 1002, 1003, 1004, 1005))
MINUS
SELECT emp_id
FROM employee
Explanation : table(sys.odcinumberlist(1000, 1001, 1002, 1003, 1004, 1005)) converts the supplied values to a table like structure with single column named EMP_ID like below. Then normal SQL MINUS operation is applied on it.
EMP_ID
------
1000
1001
1002
1003
1004
1005
(Note : sys.odcinumberlist() has limitation to take maximum 999 arguments)
Now don't ask me what exactly sys.odcinumberlist() creates internally. I am not a DB professional. Please refer http://www.dba-oracle.com/t_advanced_sql_table_expressions.htm
Upvotes: 0
Reputation: 47
Can you please let us know the Oracle database version which you are using and the output of DESC command of the Employee Table?
Also, please let us know the number of rows in your table (I.e., existing no of rows in the table) and the length/size of the list of employee IDs which you're trying to find/not-find from your table?
Also, this list of employee IDs which you have : are they stored in a File, or another table, or in a webpage, etc.? Kindly advise.
This will help answer your question further.
Regards!
Suddhasatwa
Upvotes: 0
Reputation: 35900
You can use connect by
clause to convert your list to rows and then do MINUS
operation as follows:
SQL> -- GENERATING SAME DATA AS YOUR TABLE
SQL> WITH YOUR_DATAA (EMPLOYEE_ID) AS
2 (SELECT '1001' FROM DUAL UNION ALL
3 SELECT '1002' FROM DUAL UNION ALL
4 SELECT '1004' FROM DUAL),
5 -- YOUR QUERY STARTS FROM HERE -- WITH
6 YOUR_LIST (LST) AS
7 (SELECT '1000, 1001, 1002, 1003, 1004, 1005' FROM DUAL)
8 --
9 SELECT TRIM(REGEXP_SUBSTR(LST, '[^,]+', 1, LEVEL)) AS EMPLOYEE_IDS
10 FROM YOUR_LIST
11 CONNECT BY LEVEL <= REGEXP_COUNT(LST, ',') + 1
12 MINUS
13 SELECT EMPLOYEE_ID
14 FROM YOUR_DATAA;
EMPLOYEE_IDS
--------------------------------------------------------------------------------
1000
1003
1005
SQL>
Cheers!!
Upvotes: 0
Reputation: 4061
This will do it:
select EPM_IDs
from
(
select 1000 as EPM_IDs union
select 1001 union
select 1002 union
select 1003 union
select 1004 union
select 1005
)a
where not exists(select 1 from EMPLOYEE e where a.EPM_IDs = e.EPM_IDs)
Upvotes: 1