SQL Interview Questions
SQL Interview Questions
Write a query to find the highest salary earned by an employee in each department and also the number of employees who earn the highest salary?
SELECT DEPARTMENT_ID, MAX(SALARY) HIGHEST_SALARY, COUNT(1) KEEP(DENSE_RANK LAST ORDER BY SALARY) CNT_HIGH_SAL FROM EMPLOYEES GROUP BY DEPARTMENT_ID;
2. Write a query to get the top 2 employees who are earning the highest salary in each department?
SELECT DEPARTMENT_ID, EMPLOYEE_ID, SALARY FROM ( SELECT DEPARTMENT_ID, EMPLOYEE_ID, SALARY, ROW_NUMBER() OVER(PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC ) R FROM EMPLOYEES ) A WHERE R <= 2;
DELETE
FROM EMPLOYEES
4. Write a query to find the employees who are earning more than the average salary in their department?
SELECT EMPLOYEE_ID, SALARY FROM EMPLOYEES E_O WHERE SALARY > ( SELECT AVG(SALARY) FROM EMPLOYEES E_I WHERE E_I.DEPARTMENT_ID = E_O.DEPARTMENT_ID );
6. What is a correlated Query? It is a form of sub query, where the sub query uses the values from the outer query in its WHERE clause. The sub query runs for each row processed in the outer query. Question 4 is an example for a correlated sub query.
PL/SQL Interview Questions: 1. What is a cursor? A cursor is a reference to the system memory when an SQL statement is executed. A cursor contains the information about the select statement and the rows accessed by it. 2. What is implicit cursor and explicit cursor?
Implicit Cursors: Implicit cursors are created by default when DML statements like INSERT, UPDATE and DELETE are executed in PL/SQL objects. Explicit Cursors: Explicit cursors must be created by you when executing the select statements.
%FOUND : Returns true if a DML or SELECT statement affects at least one row. %NOTFOUND: Returns true if a DML or SELECT statement does not affect at least one row. %ROWCOUNT: Returns the number of rows affected by the DML or SELECT statement. %ISOPEN: Returns true if a cursor is in open state. %BULK_ROWCOUNT: Similar to %ROWCOUNT, except it is used in bulk operations.
Public procedure: In a package, the signature of the procedure is specified in the package specification. This procedure can be called outside of the package. Private procedure: For private procedure, there wont be any signature in the package specification. So, these procedures can be called only inside the package and cannot be called outside of the package.
BEGIN INSERT INTO employees_changes (employee_id, change_date ) VALUES (:OLD.photo_tag_id, SYSDATE ); END;
First Normal Form: Duplicate columns from the same table needs to be eliminated. We have to create separate tables for each group of related data and identify each row with a unique column or set of columns (Primary Key) Second Normal Form: First it should meet the requirement of first normal form. Removes the subsets of data that apply to multiple rows of a table and place them in separate tables. Relationships must be created between the new tables and their predecessors through the use of foreign keys. Third Normal Form: First it should meet the requirements of second normal form. Remove columns that are not depending upon the primary key. Fourth Normal Form: There should not be any multi-valued dependencies.
Most databases will be in Third Normal Form 3. What is De-normalization? De-normalization is the process of optimizing the read performance of a database by adding redundant data or by grouping data. De-normalization is used in OLAP systems.
4. What is a Transaction? A transaction is a logical unit of work performed against a database in which all steps must be performed or none. 5. What are ACID properties? A database transaction must be Atomic, Consistent, Isolation and Durability.
Atomic: Transactions must be atomic. Transactions must fail or succeed as a single unit. Consistent: The database must always be in consistent state. There should not be any partial transactions Isolation: The changes made by a user should be visible only to that user until the transaction is committed. Durability: Once a transaction is committed, it should be permanent and cannot be undone.
MOLAP: The data is stored in multi-dimensional cube. The storage is not in the relational database, but in proprietary formats. ROLAP: ROLAP relies on manipulating the data stored in the RDBMS for slicing and dicing functionality. HOLAP: HOLAP combines the advantages of both MOLAP and ROLAP. For summary type information, HOLAP leverages on cube technology for faster performance. For detail information, HOLAP can drill through the cube.
7. Explain one-to-one relationship with an example? One to one relationship is a simple reference between two tables. Consider Customer and Address tables as an example. A customer can have only one address and an address references only one customer. 8. Explain one-to-many relationship with an example? One-to-many relationships can be implemented by splitting the data into two tables with a primary key and foreign key relationship. Here the row in one table is referenced by one or more rows in the other table. An example is the Employees and Departments table, where the row in the Departments table is referenced by one or more rows in the Employees table. 9. Explain many-to-many relationship with an example? Many-to-Many relationship is created between two tables by creating a junction table with the key from both the tables forming the composite primary key of the junction table. An example is Students, Subjects and Stud_Sub_junc tables. A student can opt for one or more subjects in a year. Similarly a subject can be opted by one or more students. So a junction table is created to implement the many-to-many relationship. 10. Write down the general syntax of a select statement?
INSERT INTO PRODUCTS VALUES ( 100, 'Nokia'); INSERT INTO PRODUCTS VALUES ( 200, 'IPhone'); INSERT INTO PRODUCTS VALUES ( 300, 'Samsung'); INSERT INTO PRODUCTS VALUES ( 400, 'LG'); INSERT INTO PRODUCTS VALUES ( 500, 'BlackBerry'); INSERT INTO PRODUCTS VALUES ( 600, 'Motorola'); COMMIT;
PRODUCT_ID PRODUCT_NAME ----------------------100 200 300 400 500 600 Nokia IPhone Samsung LG BlackBerry 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 PRODUCT_NAME INSERT_DATE ); INTEGER, VARCHAR2(30), 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 WHERE ) ORDER BY DBMS_RANDOM.VALUE --Random number generator in oracle. )A WHERE ROWNUM <= 2; TGT_PRODUCTS T T.PRODUCT_ID = S.PRODUCT_ID
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;
( CONTENT_ID INTEGER,
CONTENT_TYPE VARCHAR2(30) );
INSERT INTO CONTENTS VALUES (1,'MOVIE'); INSERT INTO CONTENTS VALUES (2,'MOVIE'); INSERT INTO CONTENTS VALUES (3,'AUDIO'); INSERT INTO CONTENTS VALUES (4,'AUDIO'); INSERT INTO CONTENTS VALUES (5,'MAGAZINE'); INSERT INTO CONTENTS VALUES (6,'MAGAZINE'); COMMIT;
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 LOAD_FLAG ); INTEGER, 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;
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 = 1 WHERE PRIORITY = ( SELECT DECODE( PRIORITY,(SELECT MAX(PRIORITY) FROM CONTENTS_LKP) ,1 , PRIORITY+1) FROM WHERE CONTENTS_LKP CONTENT_TYPE = (SELECT DISTINCT CONTENT_TYPE FROM TGT_CONTENTS)
);
Before starting with the interview questions, we will see the difference between the aggregate functions and analytic functions with an example. I have used SALES TABLE as an example to solve the interview questions. Please create the below sales table in your oracle database.
CREATE TABLE SALES ( SALE_ID PRODUCT_ID YEAR Quantity PRICE ); INTEGER, INTEGER, INTEGER, INTEGER, INTEGER
INSERT INTO SALES VALUES ( 1, 100, 2008, 10, 5000); INSERT INTO SALES VALUES ( 2, 100, 2009, 12, 5000); INSERT INTO SALES VALUES ( 3, 100, 2010, 25, 5000); INSERT INTO SALES VALUES ( 4, 100, 2011, 16, 5000); INSERT INTO SALES VALUES ( 5, 100, 2012, 8, 5000);
INSERT INTO SALES VALUES ( 6, 200, 2010, 10, 9000); INSERT INTO SALES VALUES ( 7, 200, 2011, 15, 9000); INSERT INTO SALES VALUES ( 8, 200, 2012, 20, 9000); INSERT INTO SALES VALUES ( 9, 200, 2008, 13, 9000); INSERT INTO SALES VALUES ( 10,200, 2009, 14, 9000);
INSERT INTO SALES VALUES ( 11, 300, 2010, 20, 7000); INSERT INTO SALES VALUES ( 12, 300, 2011, 18, 7000); INSERT INTO SALES VALUES ( 13, 300, 2012, 20, 7000); INSERT INTO SALES VALUES ( 14, 300, 2008, 17, 7000); INSERT INTO SALES VALUES ( 15, 300, 2009, 19, 7000); COMMIT;
SALE_ID PRODUCT_ID YEAR QUANTITY PRICE -------------------------------------1 2 3 4 5 6 7 8 9 10 11 12 100 100 100 100 100 200 200 200 200 200 300 300 2008 2009 2010 2011 2012 2010 2011 2012 2008 2009 2010 2011 10 12 25 16 8 10 15 20 13 14 20 18 5000 5000 5000 5000 5000 9000 9000 9000 9000 9000 7000 7000
13 14 15
20 17 19
Difference Between Aggregate and Analytic Functions: Q. Write a query to find the number of products sold in each year? The SQL query Using Aggregate functions is
SELECT Year,
YEAR
CNT
PRODUCT_ID,
Year, QUANTITY, PRICE, COUNT(1) OVER (PARTITION BY YEAR) CNT FROM SALES;
SALE_ID PRODUCT_ID YEAR QUANTITY PRICE CNT -----------------------------------------9 1 14 15 2 10 11 6 3 12 4 7 13 5 8 200 100 300 300 100 200 300 200 100 300 100 200 300 100 200 2008 2008 2008 2009 2009 2009 2010 2010 2010 2011 2011 2011 2012 2012 2012 13 10 17 19 12 14 20 10 25 18 16 15 20 8 20 9000 3 5000 3 7000 3 7000 3 5000 3 9000 3 7000 3 9000 3 5000 3 7000 3 5000 3 9000 3 7000 3 5000 3 9000 3
From the ouputs, you can observe that the aggregate functions return only one row per group whereas analytic functions keeps all the rows in the gorup. Using the aggregate functions, the select clause contains only the columns specified in group by clause and aggregate functions whereas in analytic functions you can specify all the columns in the table. The PARTITION BY clause is similar to GROUP By clause, it specifies the window of rows that the analytic funciton should operate on. I hope you got some basic idea about aggregate and analytic functions. Now lets start with solving the Interview Questions on Oracle Analytic Functions. 1. Write a SQL query using the analytic function to find the total sales(QUANTITY) of each product? Solution: SUM analytic function can be used to find the total sales. The SQL query is
SELECT PRODUCT_ID,
PRODUCT_ID QUANTITY TOT_SALES ----------------------------100 100 100 100 100 200 200 200 200 12 10 25 16 8 15 10 20 14 71 71 71 71 71 72 72 72 72
13 20 18 17 20 19
72 94 94 94 94 94
2. Write a SQL query to find the cumulative sum of sales(QUANTITY) of each product? Here first sort the QUANTITY in ascendaing order for each product and then accumulate the QUANTITY. Cumulative sum of QUANTITY for a product = QUANTITY of current row + sum of QUANTITIES all previous rows in that product. Solution: We have to use the option "ROWS UNBOUNDED PRECEDING" in the SUM analytic function to get the cumulative sum. The SQL query to get the ouput is
SELECT PRODUCT_ID, QUANTITY, SUM(QUANTITY) OVER( PARTITION BY PRODUCT_ID ORDER BY QUANTITY ASC ROWS UNBOUNDED PRECEDING) CUM_SALES FROM SALES;
100 200 200 200 200 200 300 300 300 300 300
25 10 13 14 15 20 17 18 19 20 20
71 10 23 37 52 72 17 35 54 74 94
The ORDER BY clause is used to sort the data. Here the ROWS UNBOUNDED PRECEDING option specifies that the SUM analytic function should operate on the current row and the pervious rows processed.
3. Write a SQL query to find the sum of sales of current row and previous 2 rows in a product group? Sort the data on sales and then find the sum. Solution: The sql query for the required ouput is
SELECT PRODUCT_ID, QUANTITY, SUM(QUANTITY) OVER( PARTITION BY PRODUCT_ID ORDER BY QUANTITY DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) CALC_SALES
FROM SALES;
PRODUCT_ID QUANTITY CALC_SALES -----------------------------100 100 100 100 100 200 200 200 200 200 300 300 300 300 300 25 16 12 10 8 20 15 14 13 10 20 20 19 18 17 25 41 53 38 30 20 35 49 42 37 20 40 59 57 54
The ROWS BETWEEN clause specifies the range of rows to consider for calculating the SUM. 4. Write a SQL query to find the Median of sales of a product? Solution: The SQL query for calculating the median is
SELECT PRODUCT_ID, QUANTITY, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY QUANTITY ASC) OVER (PARTITION BY PRODUCT_ID) MEDIAN FROM SALES;
PRODUCT_ID QUANTITY MEDIAN -------------------------100 100 100 100 100 200 200 200 200 200 300 300 300 300 300 8 10 12 16 25 10 13 14 15 20 17 18 19 20 20 12 12 12 12 12 14 14 14 14 14 19 19 19 19 19
5. Write a SQL query to find the minimum sales of a product without using the group by clause.
) WHERE MIN_SALE_RANK = 1;
1. Write a query to find the products whose quantity sold in a year should be greater than the average quantity 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 AND P.PRODUCT_ID = S.PRODUCT_ID S.QUANTITY > (SELECT AVG(QUANTITY) FROM SALES S1 WHERE S1.PRODUCT_ID = S.PRODUCT_ID );
PRODUCT_NAME YEAR QUANTITY -------------------------Nokia IPhone Samsung Samsung 2010 2012 2012 2010 25 20 20 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 ---------------------------------------------------
10 15 20
20 18 20
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 S_S.PRICE FROM PRODUCTS P_I, SALES S_I, PRODUCTS P_S, SALES S_S WHERE AND AND AND AND P_I.PRODUCT_ID = S_I.PRODUCT_ID P_S.PRODUCT_ID = S_S.PRODUCT_ID P_I.PRODUCT_NAME = 'IPhone' P_S.PRODUCT_NAME = 'Samsung' S_I.YEAR = S_S.YEAR IPHONE_PRICE, SAM_PRICE
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 IPhone IPhone Nokia Nokia Nokia Samsung Samsung Samsung 2011 2012 2010 2012 2011 2010 2010 2012 2011 0.333333333 0.444444444 0.222222222 0.163265306 0.326530612 0.510204082 0.344827586 0.344827586 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 Nokia
20 25
18 16
20 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
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
To solve these interview questions on SQL queries you have to create the products, sales tables in your oracle database. The "Create Table", "Insert" statements are provided below.
CREATE TABLE PRODUCTS ( PRODUCT_ID PRODUCT_NAME ); INTEGER, VARCHAR2(30)
CREATE TABLE SALES ( SALE_ID PRODUCT_ID YEAR Quantity PRICE ); INTEGER, INTEGER, INTEGER, INTEGER, INTEGER
INSERT INTO PRODUCTS VALUES ( 100, 'Nokia'); INSERT INTO PRODUCTS VALUES ( 200, 'IPhone'); INSERT INTO PRODUCTS VALUES ( 300, 'Samsung'); INSERT INTO PRODUCTS VALUES ( 400, 'LG');
INSERT INTO SALES VALUES ( 1, 100, 2010, 25, 5000); INSERT INTO SALES VALUES ( 2, 100, 2011, 16, 5000); INSERT INTO SALES VALUES ( 3, 100, 2012, 8, 5000);
INSERT INTO SALES VALUES ( 4, 200, 2010, 10, 9000); INSERT INTO SALES VALUES ( 5, 200, 2011, 15, 9000); INSERT INTO SALES VALUES ( 6, 200, 2012, 20, 9000); INSERT INTO SALES VALUES ( 7, 300, 2010, 20, 7000); INSERT INTO SALES VALUES ( 8, 300, 2011, 18, 7000); INSERT INTO SALES VALUES ( 9, 300, 2012, 20, 7000); COMMIT;
SALE_ID PRODUCT_ID YEAR QUANTITY PRICE -------------------------------------1 2 3 4 5 6 7 8 9 100 100 100 200 200 200 300 300 300 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
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 Nokia Nokia IPhone 2012 2011 2010 2012 8 16 25 20 16 25 0 15
15 10 20 18 20
10 0 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 )A GROUP BY PRODUCT_NAME HAVING MIN(QUAN_DIFF) >= 0; P.PRODUCT_ID = S.PRODUCT_ID
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 WHERE (P.PRODUCT_ID = S.PRODUCT_ID); S.QUANTITY IS NULL
PRODUCT_NAME -----------LG
PRODUCT_NAME -----------LG
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 AND P.PRODUCT_ID = S_2012.PRODUCT_ID S_2012.YEAR = 2012
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 Samsung IPhone Samsung 2010 2011 2012 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;
3 M,N Here the data in value column is a delimited by comma. Now write a query to split the delimited data in the value column into multiple rows. The output should look like as id value 1 A 1 B 1 C 2 P 2 Q 2 R 2 S 2 T 3 M 3 N Solution: SELECT t.id, CASE WHEN a.l = 1 THEN substr(value, 1, instr(value,',',1,a.l)-1) ELSE substr(value, instr(value,',',1,a.l-1)+1, CASE WHEN instr(value,',',1,a.l)-instr(value,',',1,a.l-1)-1 > 0 THEN instr(value,',',1,a.l)-instr(value,',',1,a.l-1)-1 ELSE length(value) END ) END final_value FROM t, ( SELECT level l FROM DUAL CONNECT BY LEVEL <= (SELECT Max(length(value) - length(replace(value,',',''))+1) FROM t) )a WHERE length(value) - length(replace(value,',',''))+1 >= a.l order by t.id, a.l;
empid, deptid, salary 1, 100, 5000 2, 100, 3000 3, 100, 4000 5, 200, 6000 6, 200, 8000 The below query is used to calculate the median of employee salaries across the entire table. select empid, dept_id, salary, percentile_disc(0.5) within group (order by salary desc) over () median from employees; The output of the above query is empid, deptid, salary, median 1, 100, 5000, 5000 2, 100, 3000, 5000 3, 100, 4000, 5000 5, 200, 6000, 5000 6, 200, 8000, 5000 Now we will write a query to find the median of employee salaries in each department. select empid, dept_id, salary, percentile_disc(0.5) within group (order by salary desc) over (partition by department_id) median from employees; The ouput of the above query is empid, deptid, salary, median 1, 100, 5000, 4000 2, 100, 3000, 4000 3, 100, 4000, 4000 5, 200, 6000, 7000 6, 200, 8000, 7000 The source data is represented in the form the tree structure. You can easily derive the parent-child relationship between the elements. For example, B is parent of D and E. As the element A is root element, it is at level 0. B, C are at level 1 and so on.
The above tree structure data is represented in a table as shown below. c1, A, A, A, A, A, c2, B, B, B, C, C, c3, D, D, E, F, G, c4 H I NULL NULL NULL
Here in this table, column C1 is parent of column C2, column C2 is parent of column C3, column C3 is parent of column C4. Q1. Write a query to load the target table with the below data. Here you need to generate sequence numbers for each element and then you have to get the parent id. As the element "A" is at root, it does not have any parent and its parent_id is NULL. id, element, lev, parent_id 1, A, 0, NULL 2, B, 1, 1 3, C, 1, 1 4, D, 2, 2 5, E, 2, 2 6, F, 2, 3 7, G, 2, 3 8, H, 3, 4 9, I, 3, 4 Solution: WITH t1 AS ( SELECT VALUE PARENT, LEV, LEAD(value,1) OVER (PARTITION BY r ORDER BY lev) CHILD FROM (SELECT c1, c2, c3, c4,
ROWNUM r FROM table_name ) UNPIVOT (value FOR lev IN (c1 as 0,c2 as 1,c3 as 2,c4 as 3)) ), t2 AS ( SELECT PARENT, LEV, ROWNUM SEQ FROM (SELECT DISTINCT PARENT, LEV FROM T1 ORDER BY LEV ) ), T3 AS ( SELECT DISTINCT PARENT, CHILD FROM T1 WHERE CHILD IS NOT NULL UNION ALL SELECT DISTINCT NULL, PARENT FROM T1 WHERE LEV=0 ) SELECT C.SEQ Id, T3.CHILD ELEMENT, C.LEV, P.SEQ PARENT_ID FROM T3 INNER JOIN T2 C ON (T3.CHILD = C.PARENT) LEFT OUTER JOIN T2 P ON (T3.PARENT = P.PARENT) ORDER BY C.SEQ; 1. Consider the following friends table as the source
Name, Friend_Name ----------------sam, sam, ram vamsi
vamsi, ram
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, sam, sam, sam, ram jhon vijay anand
Solution:
SELECT f1.name, f2.friend_name as friend_of_friend FROM friends f1, friends f2 WHERE AND f1.name = 'sam' 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
Solution:
SELECT f1.name, f2.friend_name as friend_of_friend FROM friends f1, friends f2 WHERE AND AND f1.name = 'sam' f1.friend_name = f2.name 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, B, C, D, 200, 155, 455, 620, 2009 2009 2009 2009
E, F, G, H, I, J, L, M,
Solution:
SELECT products, quantity_sold, year FROM ( SELECT products, quantity_sold, year, rownum r from t
4. This is an extension to the problem 3. Write a query to produce the same output using
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 )A WHERE r <= 5; t
2. Write a query to display only friday dates from Jan, 2000 to till now? Solution:
SELECT C_DATE, TO_CHAR(C_DATE,'DY') FROM ( SELECT TO_DATE('01-JAN-2000','DD-MON-YYYY')+LEVEL-1 C_DATE FROM DUAL
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, B, C, 3 5 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, A, A, B, B, B, B, B, C, 3 3 3 5 5 5 5 5 2
C,
Solution:
SELECT PRODUCTS, REPEAT 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
Solution:
SELECT SUBSTR('SMILE',LEVEL,1) A FROM DUAL
5. Convert the string "SMILE" to Ascii values? The output should look like as 83,77,73,76,69. Where
83 is the ascii value of S and so on. The ASCII function will give ascii value for only one character. If you pass a string to the ascii function, it will give the ascii value of first letter in the string. Here i am providing two solutions to get the ascii values of string. Solution1:
SELECT SUBSTR(DUMP('SMILE'),15) FROM DUAL;
Solution2:
SELECT WM_CONCAT(A) FROM ( SELECT ASCII(SUBSTR('SMILE',LEVEL,1)) A FROM DUAL