delete multiple rows from different tables on oracle - sql

I have a two table.One of them is student, the other one is salary.
Student table
id | name | code | status
1 | steven | 123 | 100
2 | joe | 678 | 200
3 | paul | 758 | 100
Salary table
id | code | status | currency
1 | 123 | 100 | euro
2 | 678 | 200 | dolar
3 | 758 | 520 | yuan
I want to delete row1 from Student table and row 1 and 2 from Salary table because code and status fields
are same.
I write that query
delete a,b Student as a , join Salary as b
on a.code= b.code and a.status = b.status
but it is not working.I want to delete rows with one query.Do you have any idea?

Would something like this do? PL/SQL, though, not SQL.
Initial data sets:
SQL> select * from student;
ID NAME CODE STATUS
---------- ------ ---------- ----------
1 steven 123 100
2 joe 678 200
3 paul 758 100
SQL> select * from salary;
ID CODE STATUS CURREN
---------- ---------- ---------- ------
1 123 100 euro
2 678 200 dollar
3 758 520 yuan
Remove common (CODE, STATUS) combinations:
SQL> begin
2 for cur_r in (select code, status from student
3 intersect
4 select code, status from salary
5 )
6 loop
7 delete from student where code = cur_r.code and status = cur_r.status;
8 delete from salary where code = cur_r.code and status = cur_r.status;
9 end loop;
10 end;
11 /
PL/SQL procedure successfully completed.
Result:
SQL> select * from student;
ID NAME CODE STATUS
---------- ------ ---------- ----------
3 paul 758 100
SQL> select * from salary;
ID CODE STATUS CURREN
---------- ---------- ---------- ------
3 758 520 yuan
SQL>

You can use two statements to do so easily:
delete student s where exists(
select * from student stu inner join salary sal on stu.code=sal.code and stu.status=sal.status and stu.id=s.id);
delete salary sal where not exists (select code from student stu where stu.code=sal.code);
First one to delete all the students having same code and status in both tables and second is to delete all the rows from salary table where code doesn't exist in student table.

Related

More than one occurrence from table

create table customer (cif number, name varchar(20),mobile number);
insert into table customer values(121,'ANT',789);
insert into table customer values(122,'ANT',789);
insert into table customer values(123,'ENT',789);
insert into customer values(124,'ENT',789);
insert into customer values(125,'BEE',123);
insert into customer values(126,'BEE',123);
insert into customer values(127,'BRO',789);
insert into customer values(128,'FIO',789);
commit;
I want retrieve data from customer table based on name and mobile more than one occurrences.
Can anyone help me out
Result like
You can use COUNT() aggregation as Analytic function along with grouping by those columns through use of PARTITION BY clause as
SELECT cif, name, mobile
FROM (SELECT c.*,
COUNT(*) OVER (PARTITION BY name, mobile) AS cnt
FROM customer c )
WHERE cnt > 1
Demo
Source:
SQL> select * From customer;
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
127 BRO 789
128 FIO 789
8 rows selected.
Based on result you posted, you're looking for rows that aren't unique per name and mobile. If that's so, here's another option:
SQL> select *
2 from customer a
3 where exists (select null
4 from customer b
5 where b.name = a.name
6 and b.mobile = a.mobile
7 group by b.name, b.mobile
8 having count(*) > 1
9 );
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
6 rows selected.
SQL>

How does select query works?

I having trouble with this query
it is executing quit well but I cannot make out
how is this select statement working.
Any help or explanation on this problem will be appreciated ..
thank you
these are my tables and query
here am looking for the employee who lives in same city as the the company for which they work
Table:-emp
eid name street city
----------- ---------------- ------------- ------------
1 yeman asd vasai
2 aksh adssd mumbai
3 chintan ghfgh mumbai
4 samual ghfdgh bandra
5 ddlj fghfgh andheri
6 jack fghnfg Bandra
7 bridge gfhfgh vasai
8 rahim ghfgh mumbai
9 chirag fghfghfg bandra
10 mistry hhhty bandra
11 ravi tytey andheri
Table:- company
cid companyname city
----------- ------------------- ------------
1 Vasai Industries vasai
2 Mumbai Pharmacy mumbai
3 bandra loft bandra
4 andheri tactics andheri
Table:= works
eid cid salary
----------- ----------- -----------
1 1 200
2 3 4831
3 4 4457
4 2 20001
5 1 32221
6 2 224
7 3 784
8 1 336
9 3 2489
10 2 4789
11 1 22541
Query
select * from emp
where eid
IN (select eid from works
where cid=(select cid from company
where city=emp.city))
why not use this query with joins and its easy to understand then a bunch of subqueries.
select * from emp
inner join works on works.eid = emp.eid
inner join company on company.city=emp.city
Explanation:
1.select cid from company where city=emp.city
Here you are getting city id regarding cities which are same in emp and company
2.
select eid from works
where cid=(select cid from company
where city=emp.city)
Here you getting collection of id's from works table which cid is same in emp and company
3.
select * from emp
where eid
IN (select eid from works
where cid=(select cid from company
where city=emp.city))
here you are getting all records based on emp id's whose cities are same in emp and city

How to bring together multiple delta tables?

I have a table with IDs and primary information. I also have two delta tables keyed on ID and date of change. I need to build a view that merges these three tables together indicating all changes over time.
Main Table:
ID Name
-- ------------------
1 Bob Jones
2 Dave Smith
First Attribute Table:
ID Date Attr1
-- ---------- -----
1 01/01/2013 25
1 02/15/2013 33
1 02/17/2013 47
1 03/02/2013 58
2 02/01/2013 1
...
Second Attribute Table
ID Date Attr2
-- ---------- -----
1 01/01/2013 ABC
1 01/05/2013 DEF
1 01/15/2013 RST
1 02/10/2013 XYZ
1 02/15/2013 Foo
1 03/05/2013 Blah
2 02/01/2013 Two
...
Based on that data, for Bob Jones, I need the view to return the following:
ID Name Date Attr1 Attr2
-- ----------- ---------- ----- -----
1 Bob Jones 01/01/2013 25 ABC
1 Bob Jones 01/05/2013 25 DEF
1 Bob Jones 01/15/2013 25 RST
1 Bob Jones 02/10/2013 25 XYZ
1 Bob Jones 02/15/2013 33 Foo
1 Bob Jones 02/17/2013 47 Foo
1 Bob Jones 03/02/2013 58 Foo
1 Bob Jones 03/05/2013 58 Blah
I tried outer joining the attribute tables to get all change values ordered by date and then used an outer join on the entire query with itself to get "prior" records:
with qry as (
select
rownum = ROW_NUMBER() OVER (ORDER BY m.ID, a.DATE),
m.ID,
m.Name,
a.DATE,
a.Attr1,
a.Attr2
from Main m
inner join (
select
COALESCE(a1.ID, a2.ID) as ID,
COALESCE(a1.LOAD_DATE, a2.LOAD_DATE) as LOAD_DATE,
a1.Attr1,
a2.Attr2
from Attributes1 a1
full outer join Attributes2 a2
on (a1.ID = a2.ID and a1.DATE = a2.DATE)
) a on (a.ID = m.ID)
)
select
COALESCE(qry.ID, prev.ID) as ID,
COALESCE(qry.Name, prev.Name) as Name,
COALESCE(qry.DATE, prev.DATE) as DATE,
COALESCE(qry.Attr1, prev.Attr1) as Attr1,
COALESCE(qry.Attr2, prev.Attr2) as Attr2,
from qry
left join qry prev
on (prev.rownum = qry.rownum - 1)
order by ID, DATE
However, that doesn't work when one attribute table changes quicker than the other because the attributes that didn't change are null in the results of the attribute table join and if two nulls show up back-to-back, the coalesce will return a null when I need the last non-null value that was in that column.
Can this even be done in a view in SQL Server 2012?

SQL - how to get certain column with MIN and MAX id for every department?

I'm trying to select some information using SQL, but with no success. Here's what I'm trying to do.
I have 2 tables:
Table employees with following columns:
IDemployee | name | surname | department_id
1 | John | Smith | 1
2 | Jane | Smith | 1
3 | Neo | Anderson | 1
4 | John | Mason | 2
5 | James | Cameron | 2
6 | Morpheus| Grumpy | 2
Table departments with columns:
IDdepartment | name
1 | Thieves
2 | Madmen
I want to select surnames of first and last employees of every department and count of their employees.
Result:
department_name | first_employee | last_employee | employee_count
Thieves | Smith | Anderson | 3
Madmen | Mason | Grumpy | 3
I was able to get count and ID's of first and last employees with following query:
SELECT d.IDdepartment, COUNT(*) as "employee_count", MIN(e.IDemployee) as "first_employee", MAX(e.IDemployee) as "last_employee"
FROM ( employees e INNER JOIN departments d ON d.IDdepartment=e.department_id)
GROUP BY d.name;
However, I can't find the right way to select their surnames. Any help would be greatly appreciated.
While there might be another way, one way is to use your query as a subquery:
SELECT d.name department_name,
e.surname first_employee,
e2.surname last_employee,
t.employee_count
FROM (
SELECT d.IDdepartment,
COUNT(*) as "employee_count",
MIN(e.IDemployee) as "first_employee",
MAX(e.IDemployee) as "last_employee"
FROM employees e
INNER JOIN departments d
ON d.IDdepartment=e.department_id
GROUP BY d.name
) t JOIN employees e on t.first_employee = e.IDemployee
JOIN employees e2 on t.last_employee = e2.IDemployee
JOIN departments d on t.IDdepartment = d.IDdepartment
And here is the fiddle: http://sqlfiddle.com/#!2/17a5b/2
Good luck.
This is general Oracle example based on existing Oracle table. You need to use analytic functions if available in your version of SQL. You do not specify which SQL you are using. If FIRST() and LAST() analytic f-ns available in your SQL then this should work:
SELECT empno, deptno, sal,
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) "Lowest",
MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) "Highest"
FROM scott.emp
ORDER BY deptno, sal
/
See lowest and highest salary by dept in output of above query:
DEPTNO SAL Lowest Highest
---------------------------------
10 1300 1300 5000
10 2450 1300 5000
10 5000 1300 5000
20 800 800 3000
20 1100 800 3000
20 2975 800 3000
....

How to update the all the table values using a singe query

hai friends
i am having the table like this
TBLKEY EMPKEY EMPNAME
----------- ------------------------------ ------------------------------
1 101 RAJA
2 105 RAJA
3 106 RAJA
4 110 RAJA
i want to to update like this
TBLKEY EMPKEY EMPNAME
----------- ------------------------------ ------------------------------
1 101 RAJA
2 105 POOJA
3 106 THRIU
4 110 POOJA
here i sholud use only one query.i run that query i sholud get the output like this not updating one by one
Try it like this:
UPDATE myTable
SET EMPNAME = CASE WHEN TBLKEY = 2 THEN 'POOJA'
WHEN TBLKEY = 3 THEN 'THRIU'
WHEN TBLKEY = 4 THEN 'POOJA' END
WHERE TBLKEY IN ( 2, 3, 4 )
Have a look:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=96260
http://www.eggheadcafe.com/community/aspnet/13/10126702/update-single-column-with-multiple-rows.aspx
Sure this links will give you idea to proceed.