SQL Interview
SQL Interview
Create a table named Employee_Test and insert some test data as:Collapse | Copy Code
CREATE TABLE Employee_Test ( Emp_ID INT Identity, Emp_name Varchar(100), Emp_Sal Decimal (10,2) ) INSERT INSERT INSERT INSERT INSERT INTO INTO INTO INTO INTO Employee_Test Employee_Test Employee_Test Employee_Test Employee_Test VALUES VALUES VALUES VALUES VALUES ('Anees',1000); ('Rick',1200); ('John',1100); ('Stephen',1300); ('Maria',1400);
Collapse | Copy Code
It is very easy to find the highest salary as:--Highest Salary select max(Emp_Sal) from Employee_Test
Now, if you are asked to find the 3rd highest salary, then the query is as:Collapse | Copy Code
--3rd Highest Salary select min(Emp_Sal) from Employee_Test where Emp_Sal in (select distinct top 3 Emp_Sal from Employee_Test order by Emp_Sal desc)
The result is as :- 1200 To find the nth highest salary, replace the top 3 with top n (n being an integer 1,2,3 etc.)
--nth Highest Salary select min(Emp_Sal) from Employee_Test where Emp_Sal in (select distinct top n Emp_Sal from Employee_Test order by Emp_Sal desc)
create table photo_test ( pgm_main_Category_id int, pgm_sub_category_id int, file_path varchar(MAX) ) insert into photo_test values (17,15,'photo/bb1.jpg'); insert insert insert insert insert insert insert into into into into into into into photo_test photo_test photo_test photo_test photo_test photo_test photo_test values(17,16,'photo/cricket1.jpg'); values(17,17,'photo/base1.jpg'); values(18,18,'photo/forest1.jpg'); values(18,19,'photo/tree1.jpg'); values(18,20,'photo/flower1.jpg'); values(19,21,'photo/laptop1.jpg'); values(19,22,'photo/camer1.jpg');
There are three groups of pgm_main_category_id each with a value of 17 (group 17 has four records),18 (group 18 has three records) and 19 (group 19 has three records). Now, if you want to select top 2 records from each group, the query is as follows:-
select pgm_main_category_id,pgm_sub_category_id,file_path from ( select pgm_main_category_id,pgm_sub_category_id,file_path, rank() over (partition by pgm_main_category_id order by pgm_sub_category_id asc) as rankid from photo_test ) photo_test where rankid < 3 -- replace 3 by any number 2,3 etc for top2 or top3. order by pgm_main_category_id,pgm_sub_category_id
pgm_main_category_id 17 17 18 18 19 19
pgm_sub_category_id 15 16 18 19 21 22
Step2 : Insert the result of the GROUP BY query into the temporary table as:Collapse | Copy Code
Step4: Fill the original table with the rows of the temporary table as:Collapse | Copy Code
Now, the duplicate rows from the main table have been removed.
Collapse | Copy Code
Emp_ID 1 2 3 4 5 6
;with T as ( select * , row_number() over (partition by Emp_ID order by Emp_ID) as rank from employee_test1 ) delete from T where rank > 1
Emp_ID 1 2 3 4 5 6
1. To 2. To 3. Find
e2.sal);
fetch
ALTERNATE
records
from
table.
(EVEN
NUMBERED)
select * from emp where rowid in (select decode(mod(rownum,2),0,rowid, null) from emp); select ALTERNATE records from a table. (ODD NUMBERED)
select * from emp where rowid in (select decode(mod(rownum,2),0,null ,rowid) from emp); 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 <=
4. Find
e2.sal);
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 >=
5. Select 6. Select
FIRST
records
from
table.
select * from emp where rownum <= &n; 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 select * from dept where deptno not in (select deptno department. 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
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
b.sal);
to
get
Min
salaries
select distinct sal from emp a where 3 >= (select count(distinct sal) from emp b where a.sal >=
10.
>= b.sal);
How
to
get
nth
max
salaries
select distinct hiredate from emp a where &n = (select count(distinct sal) from emp b where a.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. 13.
How
to
delete
duplicate
rows
in
table?
delete from emp a where rowid != (select max(rowid) from emp b where a.empno=b.empno); 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? select ename,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. with R. select * from emp where ename like'%R'; 21. Count MGR and their salary in emp table. Select all records where ename may be any no of character but it should end
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?
27.
How
to
retrive
record
where
sal
between
1000
to
2000?
28.
Select all records where dept no of both emp and dept table matches.
29.
can I
If there are two tables emp1 and emp2, and both have common record. How fetch all the recods but common records only once?
30.
How to fetch only common records from two tables emp and emp1?
31.
How can I retrive all records of emp1 those should not present in emp2?
32.
SELECT FROM GROUP
deptno wise where more than 2 employees exist. sum(sal) As totalsal emp BY deptno
SELECT * FROM PRODUCTS; PRODUCT_ID PRODUCT_NAME ----------------------100 Nokia 200 IPhone 300 Samsung 400 LG 500 BlackBerry 600 Motorola
Select only 2 products randomly. Do not select the products which are already loaded in the target table with in the last 30 days. Target table should always contain the products loaded in 30 days. It should not contain the products which are loaded prior to 30 days.
Solution: First we will create a target table. The target table will have an additional column INSERT_DATE to know when a product is loaded into the target table. The target table structure is
CREATE TABLE TGT_PRODUCTS ( PRODUCT_ID INTEGER, PRODUCT_NAME VARCHAR2(30), INSERT_DATE DATE );
The next step is to pick 5 products randomly and then load into target table. While selecting check whether the products are there in the
INSERT INTO TGT_PRODUCTS SELECT PRODUCT_ID, PRODUCT_NAME, SYSDATE INSERT_DATE FROM ( SELECT PRODUCT_ID, PRODUCT_NAME FROM PRODUCTS S WHERE NOT EXISTS ( SELECT 1 FROM TGT_PRODUCTS T WHERE T.PRODUCT_ID = S.PRODUCT_ID ) ORDER BY DBMS_RANDOM.VALUE --Random number generator in oracle. )A WHERE ROWNUM <= 2;
The last step is to delete the products from the table which are loaded 30 days back.
DELETE FROM TGT_PRODUCTS WHERE INSERT_DATE < SYSDATE - 30;
SELECT * FROM CONTENTS; CONTENT_ID CONTENT_TYPE ----------------------1 MOVIE 2 MOVIE 3 AUDIO 4 AUDIO 5 MAGAZINE 6 MAGAZINE
Load only one content type at a time into the target table. The target table should always contain only one contain type. The loading of content types should follow round-robin style. First MOVIE, second AUDIO, Third MAGAZINE and again fourth Movie.
Solution: First we will create a lookup table where we mention the priorities for the content types. The lookup table Create Statement and data is shown below.
CREATE TABLE CONTENTS_LKP ( CONTENT_TYPE VARCHAR2(30), PRIORITY INTEGER, LOAD_FLAG INTEGER ); INSERT INTO CONTENTS_LKP VALUES('MOVIE',1,1); INSERT INTO CONTENTS_LKP VALUES('AUDIO',2,0); INSERT INTO CONTENTS_LKP VALUES('MAGAZINE',3,0); COMMIT; SELECT * FROM CONTENTS_LKP; CONTENT_TYPE PRIORITY LOAD_FLAG --------------------------------MOVIE 1 1 AUDIO 2 0 MAGAZINE 3 0
Here if LOAD_FLAG is 1, then it indicates which content type needs to be loaded into the target table. Only one content type will have LOAD_FLAG as 1. The other content types will have LOAD_FLAG as 0. The target table structure is same as the source table structure. The second step is to truncate the target table before loading the data
TRUNCATE TABLE TGT_CONTENTS;
The third step is to choose the appropriate content type from the lookup table to load the source data into the target table.
INSERT INTO TGT_CONTENTS SELECT CONTENT_ID, CONTENT_TYPE FROM CONTENTS WHERE CONTENT_TYPE = (SELECT CONTENT_TYPE FROM CONTENTS_LKP WHERE LOAD_FLAG=1);
UPDATE CONTENTS_LKP SET LOAD_FLAG = 0 WHERE LOAD_FLAG = 1; UPDATE CONTENTS_LKP SET LOAD_FLAG = 1 WHERE PRIORITY = ( SELECT DECODE( PRIORITY,(SELECT MAX(PRIORITY) FROM CONTENTS_LKP) ,1 , PRIORITY+1) FROM CONTENTS_LKP WHERE CONTENT_TYPE = (SELECT DISTINCT CONTENT_TYPE FROM TGT_CONTENTS) );
INTEGER, VARCHAR2(30)
INTEGER, INTEGER, INTEGER, INTEGER, INTEGER VALUES VALUES VALUES VALUES ( ( ( ( ( ( ( ( ( ( ( ( ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 200, 300, 400, 100, 100, 100, 200, 200, 200, 300, 300, 300, 'Nokia'); 'IPhone'); 'Samsung'); 'LG'); 2010, 2011, 2012, 2010, 2011, 2012, 2010, 2011, 2012, 25, 16, 8, 10, 15, 20, 20, 18, 20, 5000); 5000); 5000); 9000); 9000); 9000); 7000); 7000); 7000);
INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO COMMIT;
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 ORDER BY S.YEAR DESC ) QUAN_PREV_YEAR FROM PRODUCTS P, SALES S WHERE P.PRODUCT_ID = S.PRODUCT_ID; PRODUCT_NAME YEAR QUANTITY QUAN_PREV_YEAR ----------------------------------------Nokia 2012 8 16 Nokia 2011 16 25 Nokia 2010 25 0 IPhone 2012 20 15 IPhone 2011 15 10 IPhone 2010 10 0
20 18 20
18 20 0
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 years 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
SELECT P.PRODUCT_NAME FROM PRODUCTS P WHERE P.PRODUCT_ID NOT IN (SELECT DISTINCT PRODUCT_ID FROM SALES); 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
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
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