Thursday 24 May 2012

Oracle Interview Questions and Answers : SQL




Q:What is the INSERT statement?
A:The INSERT statement lets you insert information into a database.
 
Q:How do you delete a record from a database?
A:Use the DELETE statement to remove records or any particular column values from a database.


Q:How could I get distinct entries from a table?
A:The SELECT statement in conjunction with DISTINCT lets you select a set of distinct values from a table in a database. The values selected from the database table would of course depend on the various conditions that are specified in the SQL query. Example
SELECT DISTINCT empname FROM emptable
 
Q:How to get the results of a Query sorted in any order?
A:You can sort the results and return the sorted results to your program by using ORDER BY keyword thus saving you the pain of carrying out the sorting yourself. The ORDER BY keyword is used for sorting.

SELECT empname, age, city FROM emptable ORDER BY empname
 
Q:How can I find the total number of records in a table?
A:You could use the COUNT keyword , example

SELECT COUNT(*) FROM emp WHERE age>40
 
Q:What is GROUP BY?
A:The GROUP BY keywords have been added to SQL because aggregate functions (like SUM) return the aggregate of all column values every time they are called. Without the GROUP BY functionality, finding the sum for each individual group of column values was not possible.
 
Q:What is the difference among "dropping a table", "truncating a table" and "deleting all records" from a table.
A:Dropping :  (Table structure  + Data are deleted), Invalidates the dependent objects ,Drops the indexesTruncating:  (Data alone deleted), Performs an automatic commit, Faster than delete
Delete : (Data alone deleted), Doesn’t perform automatic commit
 
Q:What are the Large object types suported by Oracle?
A:Blob and Clob.
 
Q:Difference between a "where" clause and a "having" clause.
A:Having clause is used only with group functions whereas Where is not used with.
 
Q:What's the difference between a primary key and a unique key?
A:Both primary key and unique enforce uniqueness of the column on which they are defined. But by default primary key creates a clustered index on the column, where are unique creates a nonclustered index by default. Another major difference is that, primary key doesn't allow NULLs, but unique key allows one NULL only.
 
Q:What are cursors? Explain different types of cursors. What are the disadvantages of cursors? How can you avoid cursors?
A:Cursors allow row-by-row prcessing of the resultsets.
Types of cursors: Static, Dynamic, Forward-only, Keyset-driven. See books online for more information.
Disadvantages of cursors: Each time you fetch a row from the cursor, it results in a network roundtrip, where as a normal SELECT query makes only one rowundtrip, however large the resultset is. Cursors are also costly because they require more resources and temporary storage (results in more IO operations). Furthere, there are restrictions on the SELECT statements that can be used with some types of cursors.
Most of the times, set based operations can be used instead of cursors.
 
Q:What are triggers? How to invoke a trigger on demand?
A:Triggers are special kind of stored procedures that get executed automatically when an INSERT, UPDATE or DELETE operation takes place on a table. Triggers can't be invoked on demand. They get triggered only when an associated action (INSERT, UPDATE, DELETE) happens on the table on which they are defined.
Triggers are generally used to implement business rules, auditing. Triggers can also be used to extend the referential integrity checks, but wherever possible, use constraints for this purpose, instead of triggers, as constraints are much faster.

Q:What is a join and explain different types of joins.
A:Joins are used in queries to explain how different tables are related. Joins also let you select data from a table depending upon data from another table.
Types of joins: INNER JOINs, OUTER JOINs, CROSS JOINs. OUTER JOINs are further classified as LEFT OUTER JOINS, RIGHT OUTER JOINS and FULL OUTER JOINS.
 
Q:What is a self join?
A:Self join is just like any other join, except that two instances of the same table will be joined in the query.





1.      To see current user name
 Sql> show user;
2.      Change SQL prompt name
 SQL> set sqlprompt “Manimara > “
Manimara >
Manimara >
3.      Switch to DOS prompt
 SQL> host
4.      How do I eliminate the duplicate rows ?
 SQL> delete from table_name where rowid not in (select max(rowid) from table group by duplicate_values_field_name);
or
SQL> delete duplicate_values_field_name dv from table_name ta where rowid <(select min(rowid)  from table_name tb where ta.dv=tb.dv);
Example.
Table Emp
Empno Ename
101               Scott
102               Jiyo
103               Millor
104               Jiyo
105               Smith
delete ename from emp a where rowid < ( select min(rowid) from emp b where a.ename = b.ename);
The output like,
Empno Ename
101               Scott
102               Millor
103               Jiyo
104               Smith
5.      How do I display row number with records?
To achive this use rownum pseudocolumn with query, like SQL> SQL> select rownum, ename from emp;
Output:
1                    Scott
2                    Millor
3                    Jiyo
4                    Smith
6.      Display the records between two range
select rownum, empno, ename  from emp  where  rowid in
 (select rowid from emp where rownum <=&upto
 minus
 select rowid from emp where rownum<&Start);
Enter value for upto: 10
Enter value for Start: 7
   ROWNUM     EMPNO ENAME
--------- --------- ----------
        1      7782 CLARK
        2      7788 SCOTT
        3      7839 KING
        4      7844 TURNER
7.      I know the nvl function only allows the same data type(ie. number or char or date Nvl(comm, 0)), if commission is null then the text “Not Applicable”  want to display, instead of blank space. How do I write the query?
 SQL> select nvl(to_char(comm.),'NA') from emp;
Output :
NVL(TO_CHAR(COMM),'NA')
-----------------------
NA
300
500
NA
1400
NA
NA
8.      Oracle cursor : Implicit & Explicit cursors
Oracle uses work areas called private SQL areas to create SQL statements.
PL/SQL construct to identify each and every work are used, is called as Cursor.
For SQL queries returning a single row, PL/SQL declares all implicit cursors.
For queries that returning more than one row, the cursor needs to be explicitly declared.
9.      Explicit Cursor attributes
 There are four cursor attributes used in Oracle
cursor_name%Found, cursor_name%NOTFOUND, cursor_name%ROWCOUNT, cursor_name%ISOPEN
10.  Implicit Cursor attributes
 Same as explicit cursor but prefixed by the word SQL
SQL%Found, SQL%NOTFOUND, SQL%ROWCOUNT, SQL%ISOPEN
Tips : 1. Here SQL%ISOPEN is false, because oracle automatically closed the implicit cursor after executing SQL statements.
       : 2.  All are  Boolean attributes.
11.  Find out nth highest salary from emp table
 SELECT DISTINCT (a.sal) FROM EMP A WHERE &N = (SELECT COUNT (DISTINCT (b.sal)) FROM EMP B WHERE a.sal<=b.sal);
Enter value for n: 2
      SAL
---------
     3700
12.  To view installed Oracle version information
 SQL> select banner from v$version;
13.  Display the number value in Words
 SQL> select sal, (to_char(to_date(sal,'j'), 'jsp'))
from emp;
the output like,
      SAL (TO_CHAR(TO_DATE(SAL,'J'),'JSP'))
--------- -----------------------------------------------------
      800 eight hundred
     1600 one thousand six hundred
     1250 one thousand two hundred fifty
If you want to add some text like,
Rs. Three Thousand only.
SQL> select sal  "Salary ",
 (' Rs. '|| (to_char(to_date(sal,'j'), 'Jsp'))|| ' only.'))
 "Sal in Words" from emp
/
Salary  Sal in Words
------- ------------------------------------------------------
    800  Rs. Eight Hundred only.
   1600  Rs. One Thousand Six Hundred only.
   1250  Rs. One Thousand Two Hundred Fifty only.
14.  Display Odd/ Even number of records
 Odd number of records:
select * from emp where (rowid,1) in (select rowid, mod(rownum,2) from emp);
1
3
5
Even number of records:
select * from emp where (rowid,0) in (select rowid, mod(rownum,2) from emp)
2
4
6
15.  Which date function returns number value?
 months_between
16.  Any three PL/SQL Exceptions?
 Too_many_rows, No_Data_Found, Value_Error, Zero_Error, Others
17.  What are PL/SQL Cursor Exceptions?
 Cursor_Already_Open, Invalid_Cursor
18.  Other way to replace query result null value with a text
 SQL> Set NULL ‘N/A’
to reset SQL> Set NULL ‘’
19.   What are the more common pseudo-columns?
 SYSDATE, USER , UID, CURVAL, NEXTVAL, ROWID, ROWNUM
20.   What is the output of SIGN function?
 1 for positive value,
0 for Zero,
-1 for Negative value.
21.  What is the maximum number of triggers, can apply to a single table?
 12 triggers.



SQL Queries Interview Questions - Oracle Part 1

As a database developer, writing SQL queries, PLSQL code is part of daily life. Having a good knowledge on SQL is really important. Here i am posting some practical examples on SQL queries.

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     INTEGER,
       PRODUCT_NAME   VARCHAR2(30)
);
CREATE TABLE SALES
(
       SALE_ID        INTEGER,
       PRODUCT_ID     INTEGER,
       YEAR           INTEGER,
       Quantity       INTEGER,
       PRICE          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;

The products table contains the below data.

SELECT * FROM PRODUCTS;

PRODUCT_ID PRODUCT_NAME
-----------------------
100        Nokia
200        IPhone
300        Samsung

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 belowSQL 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
Samsung      2012    20        18
Samsung      2011    18        20
Samsung      2010    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 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 thenfind 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
This is continuation to my previous post, SQL Queries Interview Questions - Oracle Part 1, Where i have used PRODUCTS and SALES tables as an example. Here also i am using the same tables. So, just take a look at the tables by going through that link and it will be easy for you to understand the questions mentioned here.

Solve the below examples by writing SQL queries.

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  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
Interview Questions. If you find any bugs in the queries, Please do comment. So, that i will rectify them.

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

Solution:

SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=&N;

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 
  CONNECT BY LEVEL <= 
       (SYSDATE - TO_DATE('01-JAN-2000','DD-MON-YYYY')+1) 
)
WHERE TO_CHAR(C_DATE,'DY') = 'FRI'; 

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,
       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 
CONNECT BY LEVEL <=LENGTH('SMILE');

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 
CONNECT BY LEVEL <=LENGTH('SMILE') 
);
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;
Write SQL queries for the below interview questions:
1. Load the below products table into the target table.
CREATE TABLE PRODUCTS
(
       PRODUCT_ID     INTEGER,
       PRODUCT_NAME   VARCHAR2(30)
);

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;

SELECT * FROM PRODUCTS;

PRODUCT_ID PRODUCT_NAME
-----------------------
100        Nokia
200        IPhone
300        Samsung
400        LG
500        BlackBerry
600        Motorola


The requirements for loading the target table are:
  • 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;


2. Load the below CONTENTS table into the target table.
CREATE TABLE CONTENTS
(
  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;

SELECT * FROM CONTENTS;

CONTENT_ID CONTENT_TYPE
-----------------------
1          MOVIE
2          MOVIE
3          AUDIO
4          AUDIO
5          MAGAZINE
6          MAGAZINE


The requirements to load the target table are: 
  • 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);


The last step is to update the LOAD_FLAG of the Lookup table.
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)
);


No comments:

Post a Comment