0% found this document useful (0 votes)
9 views35 pages

SQL Stuff by Venkat v1.0

The document provides various SQL queries for complex tasks such as finding the second highest salary, performing Top-N analysis, and using analytical functions like RANK and LAG. It explains the concept of inline views and demonstrates aggregate functions for calculating sales data. Additionally, it includes frequently asked SQL interview questions with corresponding solutions for tasks like fetching alternate records and handling duplicates.

Uploaded by

rams915
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views35 pages

SQL Stuff by Venkat v1.0

The document provides various SQL queries for complex tasks such as finding the second highest salary, performing Top-N analysis, and using analytical functions like RANK and LAG. It explains the concept of inline views and demonstrates aggregate functions for calculating sales data. Additionally, it includes frequently asked SQL interview questions with corresponding solutions for tasks like fetching alternate records and handling duplicates.

Uploaded by

rams915
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 35

SQL Complex Queries&Advaned Topics

For SQL topics , please go through below doc:

Solution to finding the 2nd highest salary in SQL:

1. SELECT MAX(Salary) FROM Employee


WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee );

2. select MAX(Salary) from Employee


WHERE Salary <> (select MAX(Salary) from Employee );

3. select * from (
select Emp.*, row_number() over (order by Salary DESC) rownumb
from Employee Emp
)
whererownumb = 2; /*n is nth highest salary*/

4. select * from(select ename, sal from emp ORDER BY sal DESC)WHERE ROWNUM=2; -Correlated
subquery

5. select * FROM (
selectEmployeeID, Salary,rank() over (order by Salary DESC) ranking
from Employee
)
WHERE ranking = 2;

6. SELECT *FROM Employee Emp1


WHERE (1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp1.Salary<Emp2.Salary)

(Or)

SELECT *FROM Employee Emp1


WHERE 2 = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp1.Salary<=Emp2.Salary)

(Or)

SELECT * /*This is the outer query part */


FROM Employee Emp1
WHERE (N-1) = ( /* Subquery starts here */
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary)

7. SELECT TOP 1 Salary


FROM (
SELECT DISTINCT TOP N Salary
FROM Employee
ORDER BY Salary DESC
) AS Emp
ORDER BY Salary

8. SELECT Salary FROM Employee


ORDER BY Salary DESC LIMIT n-1,1

9. SELECT Salary FROM Employee


ORDER BY Salary DESC OFFSET N-1 ROW(S)
FETCH FIRST ROW ONLY

How to do Top-N analysis in Oracle :


SelectROWNUM as RANK, ename,salfrom(select ename,sal from emp ORDER BY sal)WHERE ROWNUM<=3;
RANK ENAME SAL
-------- ---------- ----------
1 SMITH 800
2 JAMES 950
3 ADAMS 1100

What is an Inline View?

 It is not a schema object like a normal view.


 It is sub query with a name (alias) placed in the from clause of another select statement
(main query) for which it (the sub query) acts as a data source.
 The outer query will have a reference of the inline view.
 The inline view can have a GROUP BY clause, order by clause or even inline view itself can
be join.
 Inline views are useful for performing the Top-N (Top 3 sales reps or top 10 students etc)
analysis.

Top-N analysis in Oracle


selectROWNUM as RANK, ename,salfrom(select ename,sal from emp ORDER BY sal)WHERE
ROWNUM<=3;
RANK ENAME SAL
-------- ---------- ----------
1 SMITH 800
2 JAMES 950
3 ADAMS 1100
Analytical Functions:
RANK NTILE
DENSE_RANK ROW_NUMBER

The following shows the four ranking functions used in the same query. For function
specific examples, see each ranking function.

USE AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
,ROW_NUMBER() OVER (ORDER BY a.PostalCode) AS "Row Number"
,RANK() OVER (ORDER BY a.PostalCode) AS Rank
,DENSE_RANK() OVER (ORDER BY a.PostalCode) AS "Dense Rank"
,NTILE(4) OVER (ORDER BY a.PostalCode) AS Quartile
,s.SalesYTD
,a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL AND SalesYTD<> 0;

Here is the result set.

Row Dense
FirstName LastName Rank Quartile SalesYTD PostalCode
Number Rank
Michael Blythe 1 1 1 1 4557045.0459 98027
Linda Mitchell 2 1 1 1 5200475.2313 98027
Jillian Carson 3 1 1 1 3857163.6332 98027
Garrett Vargas 4 1 1 1 1764938.9859 98027
Tsvi Reiter 5 1 1 2 2811012.7151 98027
Shu Ito 6 6 2 2 3018725.4858 98055
José Saraiva 7 6 2 2 3189356.2465 98055
David Campbell 8 6 2 3 3587378.4257 98055
Tete Mensa-Annan 9 6 2 3 1931620.1835 98055
Lynn Tsoflias 10 6 2 3 1758385.926 98055
Rachel Valdez 11 6 2 4 2241204.0424 98055
Jae Pak 12 6 2 4 5015682.3752 98055
Ranjit VarkeyChudukatil 13 6 2 4 3827950.238 98055

Analytical Functions for aggregate values:


Aggregate functions work a bit differently from ranking functions, not only because of
the functions themselves, but also in terms of how the sub-clauses work. For example, aggregate
functions don’t require an ORDERBY sub-clause and can include a ROWS/RANGE sub-clause. But
first, let’s look at aggregate functions that use only the PARTITIONBY sub-clause. In the following
example, the SELECT statement uses several aggregate functions to calculate AnnualSales values
for each partition:

SELECT SalesGroup, Country, AnnualSales,


COUNT(AnnualSales) OVER(PARTITION BY SalesGroup) AS CountryCount,
SUM(AnnualSales) OVER(PARTITION BY SalesGroup) AS TotalSales,
AVG(AnnualSales) OVER(PARTITION BY SalesGroup) AS AverageSales
FROM RegionalSales
ORDER BY SalesGroup, AnnualSales DESC;

As before the statement partitions the data by sales group. In addition, for each function, I
pass in the AnnualSales column as the argument because I want to perform my calculations on
that column. The SELECT statement returns the results shown in the following table:

SalesGroup Country AnnualSales CountryCount TotalSales AverageSales


Europe United Kingdom 32000 6 123000 20500
Europe Germany 22000 6 123000 20500
Europe France 19000 6 123000 20500
Europe Italy 18000 6 123000 20500
Europe Greece 16000 6 123000 20500
Europe Spain 16000 6 123000 20500
North America Canada 32000 3 82000 27333
North America Mexico 28000 3 82000 27333
North America United States 22000 3 82000 27333
Pacific China 28000 7 143000 20428
Pacific Japan 22000 7 143000 20428
Pacific Singapore 21000 7 143000 20428
Pacific Malaysia 19000 7 143000 20428
Pacific Australia 18000 7 143000 20428
Pacific New Zealand 18000 7 143000 20428
Pacific Thailand 17000 7 143000 20428

FIRST_VALUE(),LAST_VALUE():

Analytic functions work much the same way as aggregate functions, except that the
ORDERBYsubclause is required for those functions that support the clause. In our next example,
we’ll try out the FIRST_VALUE and LAST_VALUE analytic functions. The FIRST_VALUE function
retrieves the first value from a sorted list, and the LAST_VALUE function retrieves the last value.
In the following example, the SELECT statement uses both of these functions to calculate
AnnualSales values in each sales group:

SELECT SalesGroup, Country, AnnualSales,


FIRST_VALUE(AnnualSales) OVER(PARTITION BY SalesGroup ORDER BY AnnualSales
DESC) AS HighestSales,
LAST_VALUE(AnnualSales) OVER(PARTITION BY SalesGroup ORDER BY AnnualSales
DESC) AS LowestSales
FROM RegionalSales;

Once again, I use the PARTITIONBYsubclause to partition the result set by sales group. In
addition, I use the ORDERBYsubclause to specify that the AnnualSales values be sorted in
descending order. The following table shows the results returned by the SELECT statement.

SalesGroup Country AnnualSales HighestSales LowestSales


Europe United Kingdom 32000 32000 32000
Europe Germany 22000 32000 22000
Europe France 19000 32000 19000
Europe Italy 18000 32000 18000
Europe Greece 16000 32000 16000
Europe Spain 16000 32000 16000
North America Canada 32000 32000 32000
North America Mexico 28000 32000 28000
North America United States 22000 32000 22000
Pacific China 28000 28000 28000
Pacific Japan 22000 28000 22000
Pacific Singapore 21000 28000 21000
Pacific Malaysia 19000 28000 19000
Pacific Australia 18000 28000 18000
Pacific New Zealand 18000 28000 18000
Pacific Thailand 17000 28000 17000

Lead(), Lag():

As you can see, the HighestSales and LowestSales columns now display duplicate
values for each row in a sales group, providing both the first and last value, respectively, in the
sorted AnnualSales column. You can, of course, simplify your SELECT statement to retrieve
only the necessary distinct values, as we did in an earlier example.
Now let’s look at two other analytic functions: LAG and LEAD. The LEAD function retrieves a
value from a row previous to the current one. The LAG function retrieves a value from a row after
the current one. The following SELECT statement demonstrates how to use these functions:

SELECT
SalesGroup,
Country,
AnnualSales,
LAG(AnnualSales, 1) OVER(PARTITION BY SalesGroup
ORDER BY AnnualSales DESC) AS PreviousSale,
LEAD(AnnualSales, 1) OVER(PARTITION BY SalesGroup
ORDER BY AnnualSales DESC) AS NextSale
FROM
RegionalSales;

First, notice that we pass a second argument into the functions, in this case, 1. The argument
indicates that we go one row up or down to retrieve the value from the sorted AnnualSales
values. The following table shows the results returned by the SELECT statement.

SalesGroup Country AnnualSales PreviousSale NextSale


Europe United Kingdom 32000 NULL 22000
Europe Germany 22000 32000 19000
Europe France 19000 22000 18000
Europe Italy 18000 19000 16000
Europe Greece 16000 18000 16000
Europe Spain 16000 16000 NULL
North America Canada 32000 NULL 28000
North America Mexico 28000 32000 22000
North America United States 22000 28000 NULL
Pacific China 28000 NULL 22000
Pacific Japan 22000 28000 21000
Pacific Singapore 21000 22000 19000
Pacific Malaysia 19000 21000 18000
Pacific Australia 18000 19000 18000
Pacific New Zealand 18000 18000 17000
Pacific Thailand 17000 18000 NULL

For more info on Analytical Functions go through below doc:


FAQ:These questions are the most frequently asked in interviews.
1. To fetch ALTERNATE records from a table. (EVEN NUMBERED)
select * from emp where rowid in (select decode(mod(rownum,2),0,rowid, null) from emp);
2. To select ALTERNATE records from a table. (ODD NUMBERED)
select * from emp where rowid in (select decode(mod(rownum,2),0,null ,rowid) from emp);
3. Find the 3rd MAX salary in the emp table.
select distinct sal from emp e1 where 3 = (select count(distinct sal) from emp e2 where e1.sal <=
e2.sal);
4. Find the 3rd MIN salary in the emp table.
select distinct sal from emp e1 where 3 = (select count(distinct sal) from emp e2where e1.sal >=
e2.sal);
5. Select FIRST n records from a table.
select * from emp where rownum <= &n;
6. Select LAST n records from a table
select * from emp minus select * from emp where rownum <= (select count(*) - &n from emp);
7. List dept no., Dept name for all the departments in which there are no employees in the
department.
select * from dept where deptno not in (select deptno from emp);
alternate solution: select * from dept a where not exists (select * from emp b where a.deptno =
b.deptno);
altertnate solution: select empno,ename,b.deptno,dname from emp a, dept b where
a.deptno(+) = b.deptno and empno is null;
8. How to get 3 Max salaries ?
select distinct sal from emp a where 3 >= (select count(distinct sal) from emp b where a.sal <=
b.sal) order by a.sal desc;
9. How to get 3 Min salaries ?
select distinct sal from emp a where 3 >= (select count(distinct sal) from emp b where a.sal >=
b.sal);
10. How to get nth max salaries ?
select distinct hiredate from emp a where &n = (select count(distinct sal) from emp b where
a.sal >= b.sal);
11. Select DISTINCT RECORDS from emp table.
select * from emp a where rowid = (select max(rowid) from emp b where a.empno=b.empno);
12. How to delete duplicate rows in a table?
delete from emp a where rowid != (select max(rowid) from emp b where a.empno=b.empno);
13. Count of number of employees in department wise.
select count(EMPNO), b.deptno, dname from emp a, dept b where a.deptno(+)=b.deptno
group by b.deptno,dname;

14. Suppose there is annual salary information provided by emp table. How to fetch
monthly salary of each and every employee?

selectename,sal/12 as monthlysal from emp;

15. Select all record from emp table where deptno =10 or 40.

select * from emp where deptno=30 or deptno=10;

16. Select all record from emp table where deptno=30 and sal>1500.

select * from emp where deptno=30 and sal>1500;

17. Select all record from emp where job not in SALESMAN or CLERK.

select * from emp where job not in ('SALESMAN','CLERK');

18. Select all record from emp where ename in 'BLAKE','SCOTT','KING'and'FORD'.

select * from emp where ename in('JONES','BLAKE','SCOTT','KING','FORD');

19. Select all records where ename starts with ‘S’ and its lenth is 6 char.

select * from emp where ename like'S____';

20. Select all records where ename may be any no of character but it should end with
‘R’.

select * from emp where ename like'%R';


21. Count MGR and their salary in emp table.

select count(MGR),count(sal) from emp;

22. In emp table add comm+sal as total sal .

select ename,(sal+nvl(comm,0)) as totalsal from emp;

23. Select any salary <3000 from emp table.

select * from emp where sal> any(select sal from emp where sal<3000);

24. Select all salary <3000 from emp table.

select * from emp where sal> all(select sal from emp where sal<3000);

25. Select all the employee group by deptno and sal in descending order.

select ename,deptno,sal from emp order by deptno,sal desc;

26. How can I create an empty table emp1 with same structure as emp?

Create table emp1 as select * from emp where 1=2;

27. How to retrive record where sal between 1000 to 2000?


Select * from emp where sal>=1000 And sal<2000
28. Select all records where dept no of both emp and dept table matches.
select * from emp where exists(select * from dept where emp.deptno=dept.deptno)
29. If there are two tables emp1 and emp2, and both have common record. How can I
fetch all the records but common records only once?
(Select * from emp) Union (Select * from emp1)
30. How to fetch only common records from two tables emp and emp1?
(Select * from emp) Intersect (Select * from emp1)
31. How can I retrieve all records of emp1 those should not present in emp2?
(Select * from emp) Minus (Select * from emp1)
32. Count the totalsa deptno wise where more than 2 employees exist.
SELECT deptno, sum(sal) As totalsal
FROM emp
GROUP BY deptno
HAVING COUNT(empno) > 2
33. There is a table which contains two column Student and Marks, you need to find all the
students, whose marks are greater than average marks i.e. list of above average students.
Answer: This query can be written using subquery as shown below:

SELECT student, marks from table where marks >(SELECTAVG(marks) from


table)

34. Write SQL Query to find duplicate rows in a database? and then write SQL query
to delete them?
Answer: You can use the following query to select distinct records:

SELECT*FROM emp a WHERE rowid = (SELECTMAX(rowid) FROM EMP b


WHEREa.empno=b.empno)

to Delete:

DELETEFROM emp a WHERE rowid != (SELECTMAX(rowid) FROM emp b


WHEREa.empno=b.empno);

35. How do you find all employees which are also manager? .
You have given a standard employee table with an additional column mgr_id, which
contains employee id of the manager.
Answer: You need to know about self-join to solve this problem. In Self Join, you can join two
instances of the same table to find out additional details as shown below

SELECTe.name, m.nameFROM Employee e, Employee m


WHEREe.mgr_id=m.emp_id;

Other Interview Questions:

15. What is an Index?


An index is performance tuning method of allowing faster retrieval of records from the
table. An index creates an entry for each value and it will be faster to retrieve data.

16. What are all the different types of indexes?


There are three types of indexes -.
a. Unique Index.
This indexing does not allow the field to have duplicate values if the column is unique
indexed.
Unique index can be applied automatically when primary key is defined.
b. Clustered Index.
This type of index reorders the physical order of the table and search based on the key
values.
Each table can have only one clustered index.
c. NonClustered Index.
NonClustered Index does not alter the physical order of the table and maintains logical
order of data.
Each table can have 999nonclustered indexes.

21. What are the types of subquery?


There are two types of subquery – Correlated and Non-Correlated.
A correlated subquerycannot be considered as independent query, but it can refer the
column in a table listed in the FROM the list of the main query.
A Non-Correlated sub query can be considered as independent query and the output of
Subquery is substituted in the main query.

26. What is a constraint?


Constraint can be used to specify the limit on the data type of table. Constraint can be
specified while creating or altering the table statement. Sample of constraint are:
NOT NULL.
CHECK.
DEFAULT.
UNIQUE.
PRIMARY KEY.
FOREIGN KEY

16. What is a Composite Primary Key ?


A Composite primary key is a set of columns whose values uniquely identify
every row in a table. What it means is that, a table which contains composite
primary key will be indexed based on the columns specified in the primary key.
This key will be referred in Foreign Key tables.

For example - if the combined effect of columns, "Employee_ID" and "Employee


Name" in a table is required to uniquely identify a row, it’s called a
Composite Primary Key. In this case, both the columns will be represented as
primary key.

26. What is a view?

The views are virtual tables. Unlike tables that contain data, views simply
contain queries that dynamically retrieve data when used.

33. What is the difference between Cluster and Non cluster Index?
A clustered index reorders the way records in the table are physically stored.
There can be only one clustered index per table. It makes data retrieval
faster.

A non-clustered index does not alter the way it was stored but creates a
completely separate object within the table. As a result insert and update
command will be faster.

Sql Functions:
Aggregate functions:

 Aggregate functions return a single result row based on groups of rows, rather than on single
rows.
 Aggregate functions can appear in select lists and in ORDER BY and HAVING clauses.

They are commonly used with the GROUP BY clause in a SELECT statement, where
Oracle divides the rows of a queried table or view into groups.
All aggregate functions except COUNT(*)and GROUPING ignore nulls.

These are Aggregate functions

SUM()
SELECT SUM(salary) as Sum_Sal FROM emp;
AVG()
SELECT AVG(salary) as Avg_Sal FROM emp;
Max()
MAX returns maximum value of expression.
SELECT Max(salary) as Max_Sal FROM emp;
Min()
Min returns minimum value of expression.
SELECT Min(salary) as Min_Sal FROM emp;
Count()
Count returns the number of rows in the query.
SELECT COUNT(*) as total_rec FROM emp;

Example of Aggregate Function using GROUP BY:


 To return the minimum and maximum salaries for each department in the emp table,we
can use:group by clause
SELECT department_id,MIN(salary),MAX(salary)FROM empGROUP BY dept_id;
 To return the minimum and maximum salaries for each department in the emp table
where minimum salary should be more than 5000
SELECT department_id, MIN(salary), MAX (salary)
FROM emp
WHERE MIN(salary) > 5000
GROUP BY dept_id;

Character Functions:

 It calculates the ASCII equivalent of the first character of the given input string.

ASCII(<Character>)
ascii('A') would return 65
ascii('a') would return 97
ascii('a8') would return 97

CHR(<Character>)
Returns the character equivalent of the given integer.
Example
SELECT CHR(65), CHR(97) FROM dual;
O/P A a
CONCAT(<string1>,<string2>)
This function returns String2 appended to String1.
Example:
SELECT CONCAT('Fname', 'Lname') Emp_name FROM emp;
INITCAP(<String>)
This function returns String with the first character of each word in upper case and rest of all in
lower case.
Example:
SELECT INITCAP('oracle tutorial') FROM Dual;
O/p Oracle Tutorial

instr( string1, string2 [, start_position [, nth_Appearance ] ] ):


string1 is the string to search.
string2 is the substring to search for in string1.
start_position is the position in string1 from where the search will start. This argument is
optional. If not mentioned, it defaults to 1.
The first position in the string is 1. If the start_position is negative, the function counts backward
direction.
nth_appearance is the nth appearance of string2. This is optional. If not defined, it defaults to 1.

Example:
SELECT INSTR('Character','r',1,1) POS1
, INSTR('Character','r',1,2) POS2
, INSTR('Character','a',-1,2) POS3
,INSTR('character','c',) POS4
FROM Dual;
pos1 pos2 pos3 pos4
4 9 3 6

LENGTH(<Str>)
Returns length of a string
secect length('Sql Tutorial') as len from dual;
O/p len
12
LOWER(<Str>)
This function returns a character string with all characters in lower case.
UPPER(<Str>)
This function returns a character string with all characters in upper case.

LPAD(<Str1>,<i>[,<Str2>])
This function returns the character string Str1 expanded in length to i characters, using Str2 to fill
in space as needed on the left side of Str1.
Example
SELECT LPAD('Oracle',10,'.') lapd_doted from Dual, would return ....Oracle
SELECT LPAD('RAM', 7) lapd_exa from Dual would return ' RAM'

RPAD(<Str1>,<i>[,<Str2>])
RPAD is same as LPAD but Str2 is padded at the right side

LTRIM(<Str1>[,<Str2>])
The LTRIM function removes characters from the left side of the character Srting, with all the
leftmost characters that appear in another text expression removed.
This function returns Str1 without any leading character that appears in Str2.If Str2 characters
are leading character in Str1, then Str1 is returned unchanged.
Str2 defaults to a single space.

Example

Select LTRIM('datawarehousing','ing') trim1


, LTRIM('datawarehousing ') trim2
, LTRIM(' datawarehousing') trim3
, LTRIM('datawarehousing','data') trim4 from dual

O/P : trim1 trim2 trim3


trim4

datawarehousing datawarehousing datawarehousing warehousing

RTRIM(<Str1>[,<Str2>])
Same as LTRIM but the characters are trimmed from the right side

TRIM([[<Str1>]<Str2> FROM]<Str3>)

 If present Str1 can be one of the following literal: LEADING, TRAILING, BOTH.
 This function returns Str3 with all C1(leading trailing or both) occurrences of characters in Str2
removed.
 If any of Str1,Str2 or Str3 is Null, this function returns a Null.

Str1 defaults to BOTH, and Str2 defaults to a space character.

Example
SELECT TRIM(' Oracle ') trim1, TRIM('Oracle ') trim2 FROM Dual;

Ans trim1 trim2

Oracle Oracle

It'll remove the space from both string.

REPLACE(<Str1>,<Str2>[,<Str3>]
This function returns Str1 with all occurrence of Str2 replaced with Str3
Example
SELECT REPLACE (‘Oracle’, ’Ora’, ’Arti’) replace_exa FROM Dual;
O/p replace_exa
Atricle

Essential Numeric Functions:

CEIL()

Returns the smallest integer greater than or equal to the order total of a specified orde
SELECT CEIL(239.8) FROM Dual would return 240

FLOOR()

Returns the largest integer equal to or less than value.

SELECT FLOOR(15.65) "Floor" FROM DUAL;

Floor
------
15

MOD()

Return modulus value


SELECT MOD(11,3) "Mod" FROM DUAL;

Modulus
-------
2

POWER()
SELECT POWER(3,2) "Power" FROM DUAL;

power
-------
9
ROUND (number)
SELECT ROUND(43.698,1) "Round" FROM DUAL;

Round
----------
43.7

TRUNC (number)
The TRUNC (number) function returns n1 truncated to n2 decimal places. If n2 is omitted, then
n1 is truncated to 0 places. n2 can be negative to truncate (make zero) n2 digits left of the
decimal point.
SELECT TRUNC(12.75,1) "Trunc" FROM DUAL;

Trunc
----------
12.75

SELECT TRUNC(12.75,-1) "Trunc" FROM DUAL;

Trunc
------
10

Date And Time Function:

ADD_MONTHS(date, number_of_month)
SELECT SYSDATE, ADD_MONTHS(SYSDATE,2), ADD_MONTHS(SYSDATE,-2) FROM
DUAL;
Result:
SYSDATE ADD_MONTH ADD_MONTH
------------- ------------------------------------------
10-Feb-13 10-Apr-13 10-Dec-12

EXTRACT(<type> FROM <date>)


'Type' can be YEAR, MONTH, DAY, HOUR, MIN, SECOND, TIME_ZONE_HOUR,
TIME_ZONE_MINUTE, TIME_ZONE_REGION.

SELECT SYSDATE, EXTRACT(YEAR FROM SYSDATE)YEAR, EXTRACT(DAY FROM SYSDATE)DAY ,


EXTRACT(TIMEZONE_HOUR FROM SYSTIMESTAMP) TZH FROM DUAL;
LAST_DAY(<date>)
Extract last day of month
Example:SELECT SYSDATE, LAST_DAY(SYSDATE) END_OF_MONTH FROM DUAL;

Result: SYSDATE END_OF_MO


---------- ---------------
10-Feb-13 28-Feb-13

NEXT_DAY(<date>,<day>)
SELECT NEXT_DAY('28-Feb-13','SUN') "FIRST MONDAY OF MARCH” FROM DUAL;
O/P FIRST MONDAY OF MARCH
03-Mar-13

ROUND (date[,<fmt>])
SELECT SYSDATE, ROUND(SYSDATE,'MM'), ROUND(SYSDATE,'YYYY') FROM
DUAL;
Result:SYSDATE ROUND(SYS ROUND(SYS
------------- --------------- ---------------
10-FEB-13 01-MAR-13 01-JAN-13

TRUNC(date[,<fmt>])
SELECT SYSDATE, TRUNC(SYSDATE,'MM'), TRUNC(SYSDATE,'YYYY') FROM DUAL;
Result: SYSDATE TRUNC(SYS TRUNC(SYS
------- - ------------ --------
10-FEB-13 01-FEB-13 01-JAN-13

JOINS IN ORACLE-different joins in oracle with examples:

1. The purpose of a join is to combine the data across tables.


2. A join is actually performed by the where clause which combines the specified rows of tables.

3. If a join involves in more than two tables then Oracle joins first two tables based on the joins
condition and then compares the result with the next table and so on.

TYPES

1 Equi join

2 Non-equi join

3 Self join
4 Natural join

5 Cross join

6 Outer join

 Left outer
 Right outer
 Full outer

7 Inner join (Using clause, on clause)

Assume that we have the following tables.

SQL> select * from dept;

DEPTNO DNAME LOC

10 INVENTORY HYBD

20 FINANCE BGLR

30 HR MUMBAI

SQL>select * from emp;

EMPN ENA MG DEPT


O ME JOB R NO

saket analys
111 h t 444 10

222 sudha clerk 333 20

manag
333 jagan er 111 10

madh engine
444 u er 222 40

1. EQUI JOIN
A join which contains an equal to ‘=’ operator in the joins condition.

Ex:
SQL>select empno,ename,job,dname,loc from emp e,dept d where e.deptno=d.deptno;

EMPN ENAM
O E JOB DNAME LOC

INVENTOR
111 saketh analyst Y HYBD

manage INVENTOR
333 jagan r Y HYBD

222 sudha clerk FINANCE BGLR

Using clause

SQL>select empno,ename,job ,dname,loc from emp e join dept d using(deptno);

EMPNO ENAME JOB DNAME LOC

INVENTOR
111 saketh analyst Y HYBD

INVENTOR
333 jagan manager Y HYBD

222 sudha clerk FINANCE BGLR

On clause

SQL>select empno,ename,job,dname,loc from emp e join dept d on(e.deptno=d.deptno);

EMPNO ENAME JOB DNAME LOC

111 saketh analyst INVENTORY HYBD

333 jagan manager INVENTORY HYBD

222 sudha clerk FINANCE BGLR

2. NON-EQUI JOIN
A join which contains an operator other than equal to ‘=’ in the joins condition.
Ex:SQL>select empno,ename,job,dname,loc from emp e,dept d where e.deptno > d.deptno;

EMPNO ENAME JOB DNAME LOC DeptNo

222 sudha clerk INVENTORY HYBD 20>10

444 madhu engineer INVENTORY HYBD 40>10

444 madhu engineer FINANCE BGLR 40>20

444 madhu engineer HR MUMBAI 40>30

3. SELF JOIN
Joining the table itself is called self join.

Ex: SQL>select e1.empno,e2.ename,e1.job,e2.deptno from emp e1,emp e2 where e1.empno=e2.mgr;

EMPN ENAM DEPTN


O E JOB O

111 jagan analyst 10

222 madhu clerk 40

manage
333 sudha r 20

enginee
444 saketh r 10

4. NATURAL JOIN
Natural join compares all the common columns.

Ex:SQL>select empno,ename,job,dname,loc from emp natural join dept;

EMPN ENAM
O E JOB DNAME LOC

INVENTOR
111 saketh analyst Y HYBD
manage INVENTOR
333 jagan r Y HYBD

222 sudha clerk FINANCE BGLR

5. CROSS JOIN
This will gives the cross product.

Ex:SQL>select empno,ename,job,dname,loc from emp cross join dept;

EMPN ENAM
O E JOB DNAME LOC

INVENTO
111 saketh analyst RY HYBD

INVENTO
222 sudha clerk RY HYBD

manag INVENTO
333 jagan er RY HYBD

engine INVENTO
444 madhu er RY HYBD

111 saketh analyst FINANCE BGLR

222 sudha clerk FINANCE BGLR

manag
333 jagan er FINANCE BGLR

engine
444 madhu er FINANCE BGLR

MUMB
111 saketh analyst HR AI

MUMB
222 sudha clerk HR AI

manag MUMB
333 jagan er HR AI
engine MUMB
444 madhu er HR AI

6. OUTER JOIN
Outer join gives the non-matching records along with matching records.

LEFT OUTER JOIN

This will display the all matching records and the records which are in left hand side table those
that are not in right hand side table.

Ex:SQL>select empno,ename,job,dname,loc from emp e left outer join dept d

on(e.deptno=d.deptno);

Or

SQL> select empno,ename,job,dname,loc from emp e,dept d where

e.deptno=d.deptno(+);

EMPN
O ENAME JOB DNAME LOC

111 saketh analyst INVENTORY HYBD

333 jagan manager INVENTORY HYBD

222 sudha clerk FINANCE BGLR

444 madhu engineer

RIGHT OUTER JOIN

This will display the all matching records and the records which are in right hand side table those
that are not in left hand side table.

Ex:SQL>select empno,ename,job,dname,loc from emp e right outer join dept d

on(e.deptno=d.deptno);

Or

SQL>select empno,ename,job,dname,loc from emp e,dept d where e.deptno(+) =


d.deptno;

EMPNO ENAME JOB DNAME LOC

111 saketh analyst INVENTORY HYBD

333 jagan manager INVENTORY HYBD

222 sudha clerk FINANCE BGLR

HR MUMBAI

FULL OUTER JOIN

This will display the all matching records and the non-matching records from both tables.

Ex:SQL>select empno,ename,job,dname,loc from emp e full outer join dept d

on(e.deptno=d.deptno);

EMPN ENAM
O E JOB DNAME LOC

manag INVENTO
333 jagan er RY HYBD

INVENTO
111 saketh analyst RY HYBD

222 sudha clerk FINANCE BGLR

engine
444 madhu er

MUMB
HR AI

7. INNER JOIN
This will display all the records that have matched.

Ex:SQL>select empno,ename,job,dname,loc from emp inner join dept using(deptno);

EMPNO ENAME JOB DNAME LOC

111 saketh analyst INVENTOR HYBD


Y

INVENTOR
333 jagan manager Y HYBD

222 sudha clerkx` FINANCE BGLR

Complex queris:
1. Write a query to generate sequence numbers from 1 to the specified number N?

Solution:
SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=&N;
Output: give 3  1

3. Write a query to duplicate each row based on the value in the repeat column? The input table
data looks like as below
Products, Repeat
----------------
A, 3
B, 5
C, 2

Now in the output data, the product A should be repeated 3 times, B should be repeated 5 times
and C should be repeated 2 times. The output will look like as below
Products, Repeat
----------------
A, 3
A, 3
A, 3
B, 5
B, 5
B, 5
B, 5
B, 5
C, 2
C, 2

Solution:
SELECT PRODUCTS, Gives 3 for A
REPEAT
For A 3, so gives 3 values as 1,2,3 5 for B,2 for C
FROM T,
( SELECT LEVEL L FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX(REPEAT) FROM T)
) A
WHERE T.REPEAT >= A.L
ORDER BY T.PRODUCTS;

4. Write a query to display each letter of the word "SMILE" in a separate row?
S
M
I
L
E <=5, so loop executes for 5 times.

Solution: 1 SUBSTR('SMILE',1,1)S

SELECT SUBSTR('SMILE',LEVEL,1) A 2 SUBSTR('SMILE',2,1)M ..


FROM DUAL
CONNECT BY LEVEL <=LENGTH('SMILE');

http://www.folkstalk.com/2011/12/sql-queries-interview-questions-oracle.html

The products table contains the below data.


SELECT * FROM PRODUCTS;

PRODUCT_ID PRODUCT_NAME
-----------------------
100 Nokia
200 IPhone
300 Samsung
400 LG
The sales table contains the following data.
SELECT * FROM SALES;

SALE_ID PRODUCT_ID YEAR QUANTITY PRICE


--------------------------------------
1 100 2010 25 5000
2 100 2011 16 5000
3 100 2012 8 5000
4 200 2010 10 9000
5 200 2011 15 9000
6 200 2012 20 9000
7 300 2010 20 7000
8 300 2011 18 7000
9 300 2012 20 7000

Here Quantity is the number of products sold in each year. Price is the sale price of each product.

I hope you have created the tables in your oracle database. Now try to solve the below SQL
queries.
1. Write a SQL query to find the products which have continuous increase in sales every year?

Solution:

Here “Iphone” is the only product whose sales are increasing every year.

STEP1: First we will get the previous year sales for each product. The SQL query to do this is
SELECT P.PRODUCT_NAME,
S.YEAR,
S.QUANTITY,
LEAD(S.QUANTITY,1,0) OVER (
PARTITION BY P.PRODUCT_ID Input  For 100 
ORDER BY S.YEAR DESC 1 100 2010 25
) QUAN_PREV_YEAR 2 100 2011 16
FROM PRODUCTS P, 3 100 2012 8
SALES S Year Qty Year QUAN_PREV_YEAR
WHERE P.PRODUCT_ID = S.PRODUCT_ID;
2012 82012 16

2011 16 2011 25
PRODUCT_NAME YEAR QUANTITY QUAN_PREV_YEAR
----------------------------------------- 2010 25 2010 0
Nokia 2012 8 16
Nokia 2011 16 25 Else LAG(S.QUANTITY,1,0) OVER (PARTITION
BY P.PRODUCT_ID ) QUAN_PREV_YEAR
Nokia 2010 25 0
IPhone 2012 20 15 Year Qty Year QUAN_PREV_YEAR
IPhone 2011 15 10
IPhone 2010 10 0 2010 25 2010 0
Samsung 2012 20 18
2011 16 2011 25
Samsung 2011 18 20
Samsung 2010 20 0 2012 82012 16

Here the lead analytic function will get the quantity of a product in its previous year.

STEP2: We will find the difference between the quantities of a product with its previous year’s
quantity. If this difference is greater than or equal to zero for all the rows, then the product is a
constantly increasing in sales. The final query to get the required result is
SELECT PRODUCT_NAME
FROM
(
SELECT P.PRODUCT_NAME,
S.QUANTITY -
LEAD(S.QUANTITY,1,0) OVER (
PARTITION BY P.PRODUCT_ID
ORDER BY S.YEAR DESC
) QUAN_DIFF
FROM PRODUCTS P,
SALES S
WHERE P.PRODUCT_ID = S.PRODUCT_ID
)A
GROUP BY PRODUCT_NAME
HAVING MIN(QUAN_DIFF) >= 0;

PRODUCT_NAME
------------
IPhone

2. Write a SQL query to find the products which does not have sales at all?

Solution:

“LG” is the only product which does not have sales at all. This can be achieved in three ways.

Method1: Using left outer join.


SELECT P.PRODUCT_NAME
FROM PRODUCTS P
LEFT OUTER JOIN
SALES S
ON (P.PRODUCT_ID = S.PRODUCT_ID);
WHERE S.QUANTITY IS NULL

PRODUCT_NAME
------------
LG

Method2: Using the NOT IN operator.


SELECT P.PRODUCT_NAME
FROM PRODUCTS P
WHERE P.PRODUCT_ID NOT IN
(SELECT DISTINCT PRODUCT_ID FROM SALES);

PRODUCT_NAME
------------
LG

Method3: Using the NOT EXISTS operator.


SELECT P.PRODUCT_NAME
FROM PRODUCTS P
WHERE NOT EXISTS
(SELECT 1 FROM SALES S WHERE S.PRODUCT_ID = P.PRODUCT_ID);

PRODUCT_NAME
------------
LG

3. Write a SQL query to find the products whose sales decreased in 2012 compared to 2011?

Solution:
Here Nokia is the only product whose sales decreased in year 2012 when compared with the
sales in the year 2011. The SQL query to get the required output is
SELECT P.PRODUCT_NAME
FROM PRODUCTS P,
SALES S_2012,
SALES S_2011
WHERE P.PRODUCT_ID = S_2012.PRODUCT_ID
AND S_2012.YEAR = 2012
AND S_2011.YEAR = 2011
AND S_2012.PRODUCT_ID = S_2011.PRODUCT_ID
AND S_2012.QUANTITY < S_2011.QUANTITY;

PRODUCT_NAME
------------
Nokia

4. Write a query to select the top product sold in each year?

Solution:

Nokia is the top product sold in the year 2010. Similarly, Samsung in 2011 and IPhone, Samsung
in 2012. The query for this is
SELECT PRODUCT_NAME,
YEAR
FROM
(
SELECT P.PRODUCT_NAME,
S.YEAR,
RANK() OVER (
PARTITION BY S.YEAR
ORDER BY S.QUANTITY DESC
) RNK
FROM PRODUCTS P,
SALES S
WHERE P.PRODUCT_ID = S.PRODUCT_ID
) A
WHERE RNK = 1;

PRODUCT_NAME YEAR
--------------------
Nokia 2010
Samsung 2011
IPhone 2012
Samsung 2012

5. Write a query to find the total sales of each product.?

Solution:
This is a simple query. You just need to group by the data on PRODUCT_NAME and then find
the sum of sales.
SELECT P.PRODUCT_NAME,
NVL( SUM(S.QUANTITY*S.PRICE), 0) TOTAL_SALES
FROM PRODUCTS P
LEFT OUTER JOIN
SALES S
ON (P.PRODUCT_ID = S.PRODUCT_ID)
GROUP BY P.PRODUCT_NAME;

PRODUCT_NAME TOTAL_SALES
---------------------------
LG 0
IPhone 405000
Samsung 406000
Nokia 245000

1. Write a query to find the products whose quantity sold in a year should be greater than the average
quantity of the product sold across all the years?

Solution:

This can be solved with the help of correlated query. The SQL query for this is

SELECT P.PRODUCT_NAME,
S.YEAR,
S.QUANTITY
FROM PRODUCTS P,
SALES S
WHERE P.PRODUCT_ID = S.PRODUCT_ID
AND S.QUANTITY >
(SELECT AVG(QUANTITY)
FROM SALES S1
WHERE S1.PRODUCT_ID = S.PRODUCT_ID
);

PRODUCT_NAME YEAR QUANTITY


--------------------------
Nokia 2010 25
IPhone 2012 20
Samsung 2012 20
Samsung 2010 20

2. Write a query to compare the products sales of "IPhone" and "Samsung" in each year? The output
should look like as

YEAR IPHONE_QUANT SAM_QUANT IPHONE_PRICE SAM_PRICE


---------------------------------------------------
2010 10 20 9000 7000
2011 15 18 9000 7000
2012 20 20 9000 7000
Solution:

By using self-join SQL query we can get the required result. The required SQL query is

SELECT S_I.YEAR,
S_I.QUANTITY IPHONE_QUANT,
S_S.QUANTITY SAM_QUANT,
S_I.PRICE IPHONE_PRICE,
S_S.PRICE SAM_PRICE
FROM PRODUCTS P_I,
SALES S_I,
PRODUCTS P_S,
SALES S_S
WHERE P_I.PRODUCT_ID = S_I.PRODUCT_ID
AND P_S.PRODUCT_ID = S_S.PRODUCT_ID
AND P_I.PRODUCT_NAME = 'IPhone'
AND P_S.PRODUCT_NAME = 'Samsung'
AND S_I.YEAR = S_S.YEAR

3. Write a query to find the ratios of the sales of a product?

Solution:

The ratio of a product is calculated as the total sales price in a particular year divide by the total sales
price across all years. Oracle provides RATIO_TO_REPORT analytical function for finding the ratios. The
SQL query is

SELECT P.PRODUCT_NAME,
S.YEAR,
RATIO_TO_REPORT(S.QUANTITY*S.PRICE)
OVER(PARTITION BY P.PRODUCT_NAME ) SALES_RATIO
FROM PRODUCTS P,
SALES S
WHERE (P.PRODUCT_ID = S.PRODUCT_ID);

PRODUCT_NAME YEAR RATIO


-----------------------------
IPhone 2011 0.333333333
IPhone 2012 0.444444444
IPhone 2010 0.222222222
Nokia 2012 0.163265306
Nokia 2011 0.326530612
Nokia 2010 0.510204082
Samsung 2010 0.344827586
Samsung 2012 0.344827586
Samsung 2011 0.310344828

4. In the SALES table quantity of each product is stored in rows for every year. Now write a query to
transpose the quantity for each product and display it in columns? The output should look like as
PRODUCT_NAME QUAN_2010 QUAN_2011 QUAN_2012
------------------------------------------
IPhone 10 15 20
Samsung 20 18 20
Nokia 25 16 8

Solution:

Oracle 11g provides a pivot function to transpose the row data into column data. The SQL query for this
is

SELECT * FROM
(
SELECT P.PRODUCT_NAME,
S.QUANTITY,
S.YEAR
FROM PRODUCTS P,
SALES S
WHERE (P.PRODUCT_ID = S.PRODUCT_ID)
)A
PIVOT ( MAX(QUANTITY) AS QUAN FOR (YEAR) IN (2010,2011,2012));

If you are not running oracle 11g database, then use the below query for transposing the row data into
column data.

SELECT P.PRODUCT_NAME,
MAX(DECODE(S.YEAR,2010, S.QUANTITY)) QUAN_2010,
MAX(DECODE(S.YEAR,2011, S.QUANTITY)) QUAN_2011,
MAX(DECODE(S.YEAR,2012, S.QUANTITY)) QUAN_2012
FROM PRODUCTS P,
SALES S
WHERE (P.PRODUCT_ID = S.PRODUCT_ID)
GROUP BY P.PRODUCT_NAME;

5. Write a query to find the number of products sold in each year?

Solution:

To get this result we have to group by on year and the find the count. The SQL query for this question is

SELECT YEAR,
COUNT(1) NUM_PRODUCTS
FROM SALES
GROUP BY YEAR;

YEAR NUM_PRODUCTS
------------------
2010 3
2011 3
2012 3
SQL Queries Interview Questions - Oracle Part 4
1. Consider the following friends table as the source

Name, Friend_Name
-----------------
sam, ram
sam, vamsi
vamsi, ram
vamsi, jhon
ram, vijay
ram, anand

Here ram and vamsi are friends of sam; ram and jhon are friends of vamsi and so on. Now write a query
to find friends of friends of sam. For sam; ram,jhon,vijay and anand are friends of friends. The output
should look as

Name, Friend_of_Firend
----------------------
sam, ram
sam, jhon
sam, vijay
sam, anand

Solution:

SELECT f1.name,
f2.friend_name as friend_of_friend
FROM friends f1,
friends f2
WHERE f1.name = 'sam'
AND f1.friend_name = f2.name;

2. This is an extension to the problem 1. In the output, you can see ram is displayed as friends of friends.
This is because, ram is mutual friend of sam and vamsi. Now extend the above query to exclude mutual
friends. The outuput should look as

Name, Friend_of_Friend
----------------------
sam, jhon
sam, vijay
sam, anand

Solution:

SELECT f1.name,
f2.friend_name as friend_of_friend
FROM friends f1,
friends f2
WHERE f1.name = 'sam'
AND f1.friend_name = f2.name
AND NOT EXISTS
(SELECT 1 FROM friends f3
WHERE f3.name = f1.name
AND f3.friend_name = f2.friend_name);

3. Write a query to get the top 5 products based on the quantity sold without using the row_number
analytical function? The source data looks as

Products, quantity_sold, year


-----------------------------
A, 200, 2009
B, 155, 2009
C, 455, 2009
D, 620, 2009
E, 135, 2009
F, 390, 2009
G, 999, 2010
H, 810, 2010
I, 910, 2010
J, 109, 2010
L, 260, 2010
M, 580, 2010

Solution:

SELECT products,
quantity_sold,
year
FROM
(
SELECT products,
quantity_sold,
year,
rownum r
from t
ORDER BY quantity_sold DESC
)A
WHERE r <= 5;

4. This is an extension to the problem 3. Write a query to produce the same output using row_number
analytical function?

Solution:

SELECT products,
quantity_sold,
year
FROM
(
SELECT products,
quantity_sold,
year,
row_number() OVER(
ORDER BY quantity_sold DESC) r
from t
)A
WHERE r <= 5;

5. This is an extension to the problem 3. write a query to get the top 5 products in each year based on
the quantity sold?

Solution:

SELECT products,
quantity_sold,
year
FROM
(
SELECT products,
quantity_sold,
year,
row_number() OVER(
PARTITION BY year
ORDER BY quantity_sold DESC) r
from t
)A
WHERE r <= 5;

Recommended Posts:Please visit below links to get more interview questions:

SQL Queries Interview Questions - Oracle Part 1


SQL Queries Interview Questions - Oracle Part 2
SQL Queries Interview Questions - Oracle Part 3
SQL Queries Interview Questions - Oracle Part 4
SQL Queries Interview Questions - Oracle Part 5

SQL Queries: http://www.bullraider.com/database/sql-tutorial/6-select-query?limit=1&limitstart=0

You might also like