using Not in in SubQuery with not equal to - oracle

Following two queries are resulting into different number of records by interchanging the condition in following way:
select count(1) from clientlist where userid
not in (select distinct userid from Clientlist
where userid in (select uniqueid from employee e where emplstatus = 'Y' ))
Returning 38885 number of records
select count(1) from clientlist where userid
in (select distinct userid from Clientlist
where userid in (select uniqueid from employee e where emplstatus != 'Y' ))
Returning 3630 number of records
would any one please be able to explain what difference the change in condition is causing that much difference in results?

Table ClientList Table employee
Id Id Status
-- -- ------
1 1 Y
2 2 N
3 3 null
4
First query counts id's: 2, 3, 4 - rows which are in ClientList and are not in employee and marked as Y.
Second query: id 2 - shows rows which are in both tables and in table 2 are marked as 'N'.

Related

Oracle, Select Distinct columns, with corresponding columns

I want to select DISTINCT results from the user_id column but I need the corresponding columns as well.
Result set needs to return two role_id that are Distnct user_id and be not an 'Unassigned' status.
The query I am using:
SELECT role_id, user_id, role_code, status_code FROM table where school_id=5 and status_code= 'DRAFT';
This an example of my table:
ROLE_ID USER_ID SCHOOL_ID CAMPUS_ID ROLE_CODE STATUS_CODE
1 4 5 7 Unassigned DRAFT
2 4 5 7 TEST DRAFT
3 4 5 8 TEST DRAFT
4 5 5 9 Unassigned DRAFT
5 5 5 9 TEST DRAFT
6 5 5 10 TEST DRAFT
I have tried to add group by based on user_id but I get an ORA-00979.
You can use ROW_NUMBER() to identify the rows you want. For example:
select *
from (
select t.*,
row_number() over(partition by user_id order by role_id) as rn
from t
where role_code <> 'Unassigned'
) x
where rn = 1
DISTINCT is across the entire set of columns and not for one specific column. Therefore, if you want to get the DISTINCT rows which are not Unassigned you can use:
SELECT DISTINCT
role_id,
user_id,
role_code,
status_code
FROM table
where school_id = 5
and status_code = 'DRAFT'
and role_code != 'Unassigned';
If you want to get a single row for each user_id then you can use GROUP BY and find the minimum role_id:
SELECT MIN(role_id) AS role_id,
user_id,
MIN(role_code ) KEEP (DENSE_RANK FIRST ORDER BY role_id) AS role_code,
MIN(status_code) KEEP (DENSE_RANK FIRST ORDER BY role_id) AS status_code
FROM table
where school_id = 5
and status_code = 'DRAFT'
and role_code != 'Unassigned'
GROUP BY
user_id;

Merge query to distribute equal number of records between 100 users

I have two tables in Oracle, in first table I have 100 users and in second table I have 100000 records. I want to distribute equal amount of records between them.....
Instead of writing updating and using rownum <= 1000 to distribute data....I want to write merge statement that can divide equal number of records between 100 users.
Table 1
column A Column B column c
1 Pre 90008765
2 Pre 90008766 and so on like this
Table 2
column a Column B column C Column d
1 null null null
2 null null null
And so on will have 100000 records
and between these two tables column a will be common in which we can apply join condition..... please guide me with merge query
If I understand correctly these words "write merge statement that can divide equal number of records between 100 users", you want this:
merge into table2 tgt
using (
select tb.rwd, ta.a
from (select rownum rn, a, b, c, count(1) over () cnt from table1) ta
join (select rowid rwd, rownum rn, a, b, c, d from table2) tb
on mod(ta.rn, cnt) = mod(tb.rn, cnt)) src
on (tgt.rowid = src.rwd)
when matched then update set a = src.a
dbfiddle
This statement assigns rows from T1 to rows in T2 in sequence 1-2-3-...-1-2-3-..., using function mod(). Of course you can update other columns if you need, not only A.

Oracle SQL: How to remove duplicate employee Ids from results?

I need to write query to remove duplicate employee ids among 10,000 results
EmpID name
1 x
1 x
2 y
2 y
3 z
4 A
The result should be only:
EmpID name
3 z
4 A
Select * from EMPLOYEE where ?
How can I do this?
You need aggregation :
select e.empid, e.name
from employee e
group by e.empid, e.name
having count(*) = 1;
You can try below -
Select empid,name from EMPLOYEE
group by empid,name
having count(*)=1
I would really ask you to use other than the GROUP BY method as you will be able to fetch other fields of the EMPLOYEE table along with EMPID and NAME.
Using analytical function
SELECT * FROM
(SELECT T.*, COUNT(1) OVER (PARTITION BY EMPID) AS CNT
FROM EMPLOYEE)
WHERE CNT = 1;
Using NOT EXISTS
SELECT * FROM EMPLOYEE T
WHERE NOT EXISTS
(SELECT 1 FROM EMPLOYEE TIN
WHERE TIN.ID = T.ID AND TIN.ROWID <> T.ROWID);
Cheers!!

How to write a query to select only groups where certain values are present in all rows?

I need to write a query for Oracle 11g to select only the groups which are highlighted in the image here. Specifically, there are 3 columns -- A, B, and C. Group 1 contains a null value in column C, group 2 contains several nulls in column C.Group 3 does not contain any null values in column C. Group 4 yes contains some null values in column C, and Group 5 does NOT contain any null values in column C.
I need to selects only the groups of rows that do NOT contain any null values in column C -- that would be group 3 rows and group 5 rows. I only need the group number, like return only a 3 and a 5 What SQL functions can I use to write this query? What does this query look like?
something like (pseudo code)
select colA, count(*) As cnt From tblX join to itself on something
Where ...something ...
Group By colA
(or we could skip the grouping and just select 3 and 5 or the three 3's and the three 5's)
The aggregate function COUNT(colname) would only count non-NULL values, so something like this might work:
select A from yourtable
group by A
having count(A) = count(C)
assuming A is never NULL.
You can use a not in clause and subquery
select colA, count(*) As cnt
From tblX
Where colA not in (select distinct colA from tblx where colC is null)
Group By colA

How to use the union operator in oracle

I know that the union operator is used to (for example) return all rows from two tables after eliminating duplicates. Example:
SELECT a_id
FROM a
UNION
SELECT b_id
FROM b;
The result of listing of all elements in A and B eliminating duplicates is {1,2,3,4,5,6,7,8}.
If you joined A and B you would get only {4,5}. You would have to perform a full outer join to get the full list of 1-8. My question is if I wanted to use the union operator to display from a table called employees, the employee_id and job_id ( employee id being a number data type, and job_id being a VARCHAR2 data type) How would I go about doing this?
Would it be something like this: This does not run in oracle obviously,
SELECT employee_id
UNION
SELECT job_id
FROM employees;
If you really wanted to union together all the EMPLOYEE_IDs followed by all the JOB_IDs you'd use
SELECT TO_CHAR(EMPLOYEE_ID) FROM EMPLOYEES
UNION ALL
SELECT JOB_ID FROM EMPLOYEES
If you had rows with EMPLOYEE_IDs of 1, 2, and 3, and those same rows had JOB_IDs of 1, 11, and 111 you'd get a result set of six rows with a single column which would have values of
1
2
3
1
11
111
By using UNION ALL Oracle will allow the duplicates to pass through.
Share and enjoy.

Resources