Joins SubQueries Group By
Joins
A join is a query that combines rows from two or more tables, views, or materialized
views. Oracle performs a join whenever multiple tables appear in the query's FROM
clause. The query's select list can select any columns from any of these tables. If any
two of these tables have a column name in common, you must qualify all references to
these columns throughout the query with table names to avoid ambiguity.
Join Conditions
Most join queries contain WHERE clause conditions that compare two columns, each
from a different table. Such a condition is called a join condition. To execute a join,
Oracle combines pairs of rows, each containing one row from each table, for which the
join condition evaluates to TRUE. The columns in the join conditions need not also
appear in the select list.
Equijoins
An equijoin is a join with a join condition containing an equality operator ( = ). An equijoin
combines rows that have equivalent values for the specified columns.
For example the following query returns empno,name,sal,deptno and department name
and city from department table.
select emp.empno,emp.ename,emp.sal,emp.deptno,dept.dname,dept.city from
emp,dept where emp.deptno=dept.deptno;
The above query can also be written like, using aliases, given below.
select e.empno, e.ename, e.sal, e.deptno, d.dname, d.city from
emp e, dept d where emp.deptno=dept.deptno;
The above query can also be written like given below without using table qualifiers.
select empno,ename,sal,dname,city from emp,dept where
emp.deptno=dept.deptno;
And if you want to see all the columns of both tables then the query can be written like
this.
select * from emp,dept where emp.deptno=dept.deptno;
Non Equi Joins.
Non equi joins is used to return result from two or more tables where exact join is not
possible.
For example we have emp table and salgrade table. The salgrade table contains grade
and their low salary and high salary. Suppose you want to find the grade of employees
based on their salaries then you can use NON EQUI join.
select e.empno, e.ename, e.sal, s.grade from emp e, salgrade s
where e.sal between s.lowsal and s.hisal
Self Joins
A self join is a join of a table to itself. This table appears twice in the FROM clause and is
followed by table aliases that qualify column names in the join condition. To perform a
self join, Oracle combines and returns rows of the table that satisfy the join condition.
For example the following query returns employee names and their manager names for
whom they are working.
Select e.empno, e.ename, m.ename “Manager” from emp e,
emp m where e.mgrid=m.empno
Inner Join
An inner join (sometimes called a "simple join") is a join of two or more tables that
returns only those rows that satisfy the join condition.
Outer Joins
An outer join extends the result of a simple join. An outer join returns all rows that satisfy
the join condition and also returns some or all of those rows from one table for which no
rows from the other satisfy the join condition.
To write a query that performs an outer join of tables A and B and returns all rows
from A (a left outer join), use the ANSI LEFT [OUTER] JOIN syntax, or apply the
outer join operator (+) to all columns of B in the join condition. For all rows in A
that have no matching rows in B, Oracle returns null for any select list
expressions containing columns of B.
To write a query that performs an outer join of tables A and B and returns all rows
from B (a right outer join), use the ANSI RIGHT [OUTER] syntax, or apply the
outer join operator (+) to all columns of A in the join condition. For all rows in B
that have no matching rows in A, Oracle returns null for any select list
expressions containing columns of A.
To write a query that performs an outer join and and returns all rows from A and
B, extended with nulls if they do not satisfy the join condition (a full outer join),
use the ANSI FULL [OUTER] JOIN syntax.
For example the following query returns all the employees and department names and
even those department names where no employee is working.
select e.empno,e.ename,e.sal,e.deptno,d.dname,d.city from emp e,
dept d
where e.deptno(+)=d.deptno;
That is specify the (+) sign to the column which is lacking values.
Cartesian Products
If two tables in a join query have no join condition, Oracle returns their Cartesian
product. Oracle combines each row of one table with each row of the other. A Cartesian
product always generates many rows and is rarely useful. For example, the Cartesian
product of two tables, each with 100 rows, has 10,000 rows. Always include a join
condition unless you specifically need a Cartesian product.
SUBQUERIES
A query nested within a query is known as subquery.
For example, you want to see all the employees whose salary is above average salary.
For this you have to first compute the average salary using AVG function and then
compare employees salaries with this computed salary. This is possible using subquery.
Here the sub query will first compute the average salary and then main query will
execute.
Select * from emp where sal > (select avg(sal) from emp);
Similarly we want to see the name and empno of that employee whose salary is
maximum.
Select * from emp where sal = (select max(sal) from emp);
To see second maximum salary
Select max(sal) from emp where
sal < (select max(sal) from emp);
Similarly to see the Third highest salary.
Select max(sal) from emp where
sal < (select max(sal) from emp where
sal < (select max(sal) from emp));
We want to see how many employees are there whose salary is above average.
Select count(*) from emp where
sal > (select max(sal) from emp);
We want to see those employees who are working in Hyderabad. Remember emp and
dept are joined on deptno and city column is in the dept table. Assuming that wherever
the department is located the employee is working in that city.
Select * from emp where deptno
in (select deptno from dept where city=’HYD’);
You can also use subquery in FROM clause of SELECT statement.
For example the following query returns the top 5 salaries from employees table.
Select sal from (select sal from emp order by sal desc)
where rownum <= 5;
To see the sum salary deptwise you can give the following query.
Select sum(sal) from emp group by deptno;
Now to see the average total salary deptwise you can give a sub query in FROM clause.
select avg(depttotal) from (select sum(sal) as depttotal from
emp group by deptno);
WITH
The above average total salary department wise can also be achieved from Oracle
Version 9i using WITH clause given below
WITH
DEPTOT AS (select sum(sal) as dsal from emp
group by deptno)
select avg(dsal) from deptot;
GROUP BY QUERIES
You can group query results on some column values. When you give a SELECT
statement without group by clause then all the resultant rows are treated as a single
group.
For Example, we want to see the sum salary of all employees dept wise. Then the
following query will achieved the result
Select deptno,sum(sal) from emp group by deptno;
Similarly we want to see the average salary dept wise
Select deptno,avg(sal) from emp group by deptno;
Similarly we want to see the maximum salary in each department.
Select deptno,max(sal) from emp group by deptno;
Similarly the minimum salary.
Select deptno,min(sal) from emp group by deptno;
Now we want to see the number of employees working in each department.
Select deptno,count(*) from emp group by deptno;
Now we want to see total salary department wise where the dept wise total salary is
above 5000.
For this you have to use HAVING clause. Remember HAVING clause is used to filter
groups and WHERE clause is used to filter rows. You cannot use WHERE clause to filter
groups.
select deptno,sum(sal) from emp group by deptno
having sum(sal) >= 5000;
We want to see those departments and the number of employees working in them
where the number of employees is more than 2.
Select deptno, count(*) from emp group by deptno
having count(*) >=2;
Instead of displaying deptno you can also display deptnames by using join conditions.
For example we want to see deptname and average salary of them.
Select dname,avg(sal) from emp,dept
where emp.deptno=dept.deptno group by dname;
Similarly to see sum of sal.
Select dname,sum(sal) from emp,dept
where emp.deptno=dept.deptno group by dname;
We want to see the cities name and the no of employees working in each city.
Remember emp and dept are joined on deptno and city column is in the dept table.
Assuming that wherever the department is located the employee is working in that city.
Select dept.city,count(empno) from emp,dept
where emp.deptno=dept.deptno
Group by dept.city;