Tracking missing records between migrated tables in oracle - oracle

I have a table called TABLE1 as follow
ID | SP_NUMBER |CATEGORY
------------------------
1 101 A
2 101 B
3 101 C
4 102 A
5 102 B
6 103 A
7 103 C
suppose I migrated above table data to new table called TABLE2
ID | SP_NUMBER |CATEGORY
------------------------
1 101 A
2 101 C
3 102 A
4 102 B
5 103 C
Note that , after the migration TABLE2 missing some records. I want genarelise way to track those missing data
as a example I need to show
101 B
103 A
are not migrated.

Use MINUS
select sp_number,category FROM TABLE1 MINUS
SELECT sp_number,category from TABLE2;
Demo

Related

Oracle- count the number rows based on a condition

I want to create a 'ticket' which counts the number of passes for each ID. When we have a gold pass on any of the ID, this means the pass is applied to all those in booking. So for this example, we want to count 5. For the other pass_codes, we want to simply count the number of passes and exclude those that are nulls. I have an expected output below.
Say I have this data:
Passes
ID | GuestID | Pass_code
----------------------------
100 | 001 | Bronze
100 | 002 | Bronze
101 | 103 | Gold
101 | 104 | NULL
101 | 105 | NULL
101 | 106 | NULL
101 | 107 | NULL
102 | 208 | Silver
103 | 209 | Steel
103 | 210 | Steel
103 | 211 | NULL
Passengers
ID | Passengers
-----------------
100 | 2
101 | 5
102 | 1
103 | 3
I want to count then create a ticket in the output of:
ID 100 | 2 pass (bronze)
ID 101 | 5 pass (because it is gold, we count all passengers)
ID 102 | 1 pass (silver)
ID 103 | 2 pass (steel) (2 passes rather than than 3 as we just want to count only the passes for steel, bronze silver)
I want to do something like this, but as a combined query.
DECLARE #ID = 101; -- i will want to pass in IDs
-- for gold, we want to count all passengers when the gold pass is on
SELECT pp.Passengers
FROM passes
JOIN Passengers pp ON p.ID = pp.ID
WHERE p.pass_code IN'%gold%'
AND PP.id = #id
-- for bronze, silver and steel
SELECT
count(p.ID)
FROM Passes
WHERE p.ID = #id
AND P.pass_code IN ('Bronze', 'silver', 'steel') -- Dont want to check based on NUlls as this may chnage to something else.
)
Any help or advice would be much appreciated.
Does this work for you?
with Passes as (
select 100 as id, 001 as guestid, 'Bronze' as passcode from dual union all
select 100 as id, 002 as guestid, 'Bronze' as passcode from dual union all
select 101 as id, 103 as guestid,'Gold' as passcode from dual union all
select 101 as id, 104 as guestid, NULL as passcode from dual union all
select 101 as id, 105 as guestid, NULL as passcode from dual union all
select 101 as id, 106 as guestid, NULL as passcode from dual union all
select 101 as id, 107 as guestid, NULL as passcode from dual union all
select 102 as id, 208 as guestid, 'Silver' as passcode from dual union all
select 103 as id, 209 as guestid, 'Steel' as passcode from dual union all
select 103 as id, 210 as guestid, 'Steel' as passcode from dual union all
select 103 as id, 211 as guestid, NULL as passcode from dual
)
SELECT
id,passcode,count(ID)
FROM Passes
where passcode is not null and passcode<>'Gold'
group by id,passcode
union all
SELECT
id,'Gold',count(ID)
FROM Passes
where id in
(
select id from Passes where passcode='Gold'
)
group by id
order by id
result:
100 Bronze 2
101 Gold 5
102 Silver 1
103 Steel 2
If I understand your question right the query should be like the following
** The table
create table test (ID number, GuestId number, Pass_code varchar2(10));
insert into test values(100,001,'Bronze');
insert into test values(100,002,'Bronze');
insert into test values(101,103,'Gold');
insert into test values(101,104,NULL);
insert into test values(101,105,NULL);
insert into test values(101,106,NULL);
insert into test values(101,107,NULL);
insert into test values(102,208,'Silver');
insert into test values(103,209,'Steel');
insert into test values(103,210,'Steel');
insert into test values(103,211,NULL);
commit;
SQL> select * from test order by 1,2;
ID GUESTID PASS_CODE
---------- ---------- ------------------------------
100 1 Bronze
100 2 Bronze
101 103 Gold
101 104
101 105
101 106
101 107
102 208 Silver
103 209 Steel
103 210 Steel
103 211
11 rows selected.
** The query
WITH PASSES AS (
SELECT T1.ID,T1.PASS_CODE, COUNT(T2.ID) QUANTITY FROM TEST T1, TEST T2
WHERE T1.PASS_CODE='Gold' AND T1.ID=T2.ID
GROUP BY T1.ID,T1.PASS_CODE
UNION ALL
SELECT ID,PASS_CODE, COUNT(*) QUANTITY FROM TEST
WHERE PASS_CODE IS NOT NULL AND
PASS_CODE != 'Gold'
GROUP BY ID,PASS_CODE)
SELECT ID, QUANTITY || ' (' || PASS_CODE || ')' RESULT FROM PASSES
ORDER BY ID;
** Result
ID RESULT
---------- --------------------
100 2 (Bronze)
101 5 (Gold)
102 1 (Silver)
103 2 (Steel)

Extend Parent Child Hierarchy records in Oracle to display the root record of the Parent record

Here's my data:
SalesEmp SalesMgr Trty
002 009 1
002 009 2
003 009 3
009 010 9
010 (null) 10
I am able to create hierarchies using Oracle Hierarchy (CONNECT_BY_ROOT & PRIOR) and get the output as below and store it in a table (say T1):
SalesEmp Trty LVL
002 1 1
002 2 1
003 3 1
009 1 2
009 2 2
009 3 2
009 9 2
010 1 3
010 2 3
010 3 3
010 9 2
010 10 1
For processing the records further in the application, I wish to know the child record mgr's have derived their territories from. Like:-
SalesEmp Trty LVL Child_Record
002 1 1 (null)
002 2 1 (null)
003 3 1 (null)
009 1 2 002
009 2 2 002
009 3 2 003
009 9 1 (null)
010 1 3 002
010 2 3 002
010 3 3 003
010 9 2 009
010 10 1 (null)
How can I achieve this?
Looks like you only need to add prior emp as selected column:
-- sample data
with t(emp, mgr, trty) as (
select '002', '009', 1 from dual union all
select '002', '009', 2 from dual union all
select '003', '009', 3 from dual union all
select '009', null, 9 from dual )
-- end of sample data
select emp, connect_by_root(trty) trty, level, prior emp as child
from t connect by emp = prior mgr
order by level, emp, trty, prior emp
Result:
EMP TRTY LEVEL CHILD
--- ---------- ---------- -----
002 1 1
002 2 1
003 3 1 -- missing in your output
009 9 1 -- different level
009 1 2 002
009 2 2 002
009 3 2 003
... but the row I marked is at level one, so I'm not sure if this is your typo or if I didn't catch your logic. Also row for emp 003 is missing. If it's not typo then please show your query which produced first output (T1).
Edit:
For level 3, the child is shown as 009 for the child records (...) I
want it to be the root.
So please use connect_by_root for child column also. This query returns values as listed in your example in column child2:
SQLFiddle demo
select emp, connect_by_root(trty) trty, level,
prior emp as child1,
connect_by_root(emp) child2
from t connect by emp = prior mgr
order by level, emp, trty, prior emp
I believe this will help you - you can LEFT JOIN your original table to your hierarchy query, connecting their TRTY and your querys' SalesEmp to original tables' SalesMng:
SELECT your_query.salesemp,
your_query.trty,
your_query.lvl,
orig_table.salesemp
FROM your_query
LEFT JOIN orig_table ON (orig_table.salesmgr = your_query.salesemp AND orig_table.trty = your_query.trty)
ORDER BY your_query.salesemp, your_query.trty, your_query.lvl, orig_table.salesemp

Count Different Values in Oracle Using Outer Joins

My question is about left outer join with counter. I have two tables.
employee:
empid empname
----- -------
101 Tom
102 Jerry
103 Jack
104 Tim
allocation:
generator analyzer tester
--------- -------- ------
101 102 103
103 102 101
102 101 104
I need following result
empid empname generator analyzer tester
------ ------- --------- -------- -------
101 Tom 1 1 1
102 Jerry 1 2 0
103 Jack 1 0 1
104 Tim 0 0 1
I need to count the values of each task. Tom has generated 1, analyzed 1
and tested 1. Like that i need to count the values. Is this possible in
SQL. If this is possible please help me to get output.
I am getting the result. but it is not expected. I have used outer joins to solve the problem,
select
e.empid,
e.empname,
count(a1.generator),
count(a2.analyzer),
count(a3.tester)
from employee e
left join allocation a1
on e.empid=a1.author
left join allocation a2
on e.empid=a2.reviewer
left join allocation a3
on e.empid=a3.tester
group by
e.empid,
e.empname;
You can achieve it with this:
Select empid,sum(generaor),sum(analyzer),sum(tester)
from
(
Select empid,count(a.generaor) generaor,0 analyzer,0 tester
from employee
JOIN Allocation a on empid=a.generaor group by empid,a.generaor
UNION
Select empid,0 generaor,count(b.analyzer)analyzer,0 tester
from employee
JOIN Allocation b on empid=b.analyzer group by empid,b.analyzer
UNION
Select empid,0 generaor,0 analyzer,count(c.tester) tester
from employee
JOIN Allocation c on empid=c.tester group by empid,c.tester
) stag
group by empid
Try this
SELECT empid, empname, sum(generator), sum(analyzer), sum(tester) FROM
(SELECT e.empid, e.empname, count(a1.generator) generator, 0 analyzer, 0 tester
FROM Employee e
JOIN Allocation a1 ON a1.generator = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, count(a2.analyzer) analyzer, 0 tester
FROM Employee e
JOIN Allocation a2 ON a2.analyzer = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, 0 analyzer, count(a3.tester) tester
FROM Employee e
JOIN Allocation a3 ON a3.tester = e.empid
GROUP BY e.empname) tmp
GROUP BY empname
ORDER BY empid

How do I get both the child and one upper level parent information by using oracle connect by prior?

I want to get both the child and one upper level parent information by using oracle connect by prior?
For example the folowing query retrieve child info and parent id,
SELECT last_name, employee_id, manager_id, LEVEL
FROM employees
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id
but I want to get parent info also like
LAST_NAME EMPLOYEE_ID MANAGER_ID LEVEL MANAGER_NAME
------------------------- ----------- ---------- ----------------------------
King 100 1 ?
Cambrault 148 100 2 ?
Bates 172 148 3 ?
Bloom 169 148 3 .
Fox 170 148 3 .
How can I handle this problem, when I applied left join after selecting childs by connect by prior,The objects order is mixing.
You can refer to prior values in the select list:
SELECT last_name, employee_id, manager_id, LEVEL, prior last_name as manager_name
FROM employees
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id;
LAST_NAME EMPLOYEE_ID MANAGER_ID LEVEL MANAGER_NAME
------------------------- ----------- ---------- ---------- -------------------------
King 100 1
Kochhar 101 100 2 King
Greenberg 108 101 3 Kochhar
Faviet 109 108 4 Greenberg
...
Cambrault 148 100 2 King
Bates 172 148 3 Cambrault
Bloom 169 148 3 Cambrault
Fox 170 148 3 Cambrault
...

sql query to get the column data in one row

I have below data in a table called data_tab
sn code
2 101
2
2 202
5 103
5
5
How can i query to see result in one row, like
sn code1 code2 code3
2 101 202
5 103
Hi This gives the intented output ... take a look here
select sn,
max(decode(rn,1,code)) as CODE_1
,max(decode(rn,2,code)) as CODE_2
,max(decode(rn,3,code)) as CODE_3
from
(
select sn,
code,
row_number() over (partition by sn order by null ) rn
from test
)
group by sn

Resources