Search This Blog

Thursday, August 30, 2012

SQL Queries Interview Questions - Oracle Part 3

SQL Queries Interview Questions

1. 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);


2. 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;


3. 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;


4. 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;

5. 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;

6. 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