0% found this document useful (0 votes)
195 views

SQL - Examples - FB Interview

The document provides examples of SQL queries using various SQL concepts like joins, set operators, analytical functions, pivoting, unpivoting etc. It includes examples to find unmatched records between tables using minus operator or outer join, cumulative sum using analytical functions, pivoting with aggregate functions, unpivoting records, using LAG and LEAD functions to access previous/next records, generating sequential numbers using CONNECT BY, and identifying even and odd numbers.

Uploaded by

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

SQL - Examples - FB Interview

The document provides examples of SQL queries using various SQL concepts like joins, set operators, analytical functions, pivoting, unpivoting etc. It includes examples to find unmatched records between tables using minus operator or outer join, cumulative sum using analytical functions, pivoting with aggregate functions, unpivoting records, using LAG and LEAD functions to access previous/next records, generating sequential numbers using CONNECT BY, and identifying even and odd numbers.

Uploaded by

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

Question : Show the only values from table a which doesnt exists in table b :

Answer : There are multiple way to find this i.e., either you can use either set
operator or outer join. Which to use depends on the requirement.

Option 1)
select customer_id from a
minus
select customer_id from b

option 2)

select a.*
from a
, b
where a.customer_id=b.customer_id(+)
and b.customer_id is null;

-----------------------------------------------------------------------------------
----------------

select empno , ename , deptno , sal as cumulative_salary


, sum(sal) over( order by deptno , ename )
from emp

empno , ename , deptno , sal , cumulative_salary


7782 CLARK 10 3000 3000
7839 KING 10 5000 8000
7934 MILLER 10 1300 9300
7876 ADAMS 20 1100 10400
7902 FORD 20 3000 13400
7566 JONES 20 2975 16375
7788 SCOTT 20 3000 19375
7369 SMITH 20 800 20175
7499 ALLEN 30 1600 21775
7698 BLAKE 30 2850 24625
7900 JAMES 30 950 25575
7654 MARTIN 30 1250 26825
7844 TURNER 30 1500 28325
7521 WARD 30 1250 29575

-- Below example is how to avoid group by and still use aggregate functions with
other columns :
select empno , ename , deptno , sal , sum(sal) over( order by null ) -- is same as
select sum(sal) over() from emp
from emp

7521 WARD 30 1250 29575


7844 TURNER 30 1500 29575

-- sum(sal) over( order by deptno ) will provide cumulative_salary by


departments :
-- note : parttion by deptno will give you sum of sal at dept level and not
cumulative.

10 9300
10 9300
20 20175
30 29575
-- cumulative salary total, row by row, by department
SUM(sal) OVER (PARTITION BY department_id ORDER BY last_name, first_name)

10 3000 3000
10 5000 8000
10 1300 9300
20 1100 1100
20 3000 4100
20 2975 7075

-- cummalitive by salary value at dept level


sum(sal) OVER (PARTITION BY department_id ORDER BY salary) department_total

10 60000 120000
10 60000 120000
10 70000 190000
20 65000 65000

-----------------------------------

unpivot :

with sale_stats
( id, fiscal_year, product_a, product_b, product_c )
as (select 1, 2017, to_number(NULL) , 200 , 300 from
dual union all
select 2, 2018, 150 , to_number(NULL), 250 from
dual union all
select 3, 2019, 150 , 220 , to_number(NULL) from
dual
)
select * from sale_stats
unpivot
( quantity -- which is a column that represents the unpivoted values from the
product_a, product_b, and product_c columns.
for product_code -- this is a column which represents column name
in ( product_a as 'A',
-- product_b AS 'B',
product_c AS 'C'
)
)
order by product_code
;

id fiscal_year product_a product_code quatity


2 2018 null A 150
3 2019 220 A 150
2 2018 null C 250
1 2017 200 C 300

------------------------------------------------------------

pivot : counting number of employee in every deptno by job

select *
from ( select deptno,job from emp )
pivot
( count(*) -- this count` wil be applied for every job at deptno and other column
if in select clause.
for deptno in (10 dept_10 -- this deptno row value will be converted to column
header ( row got converted to column )
,20
,30)
)

job dept_10 20 30
------ ---- -- --
CLERK 1 2 1
SALESMAN 0 0 4
PRESIDENT 1 0 0
MANAGER 1 1 1
ANALYST 0 2 0

with
property(prop_name, prop_type, prop_val, environment) as (
select 'BANKING', 'A', 'true' , 'DEV' from dual union all
select 'BANKING', 'A', 'false' , 'DEV' from dual union all
select 'BANKING', 'A', 'true' , 'PROD' from dual union all
select 'BURGER' , 'B', 'true' , 'DEV' from dual union all
select 'BURGER' , 'C', 'true' , 'DEV' from dual
)
select *
from property
pivot (-- max(prop_val)
listagg(prop_val, ',') within group (order by null)
for environment in ('DEV' dev, 'TEST' test, 'STAGE' stage, 'UAT' uat,
'PROD' prod)) -- row to columns
;

prop_name , prop_type , dev , test, stage , uat , prod


--------- --------- --- ---- ----- ---- -----
BANKING A true,false true
BURGER C true
BURGER B true

pivot (max(prop_val) as v , max(prop_type) as t --listagg(prop_val, ',') within


group (order by null)
for environment in ('DEV' dev, 'TEST' test, 'STAGE' stage, 'UAT' uat))

---------------------------------------------------------

lead and lag : --its a analytical function so no need of group by

SELECT EMPNO , ENAME , SAL


, LEAD(SAL, 1) OVER (ORDER BY EMPNO DESC ) LEAD_SAL -- cannot be used in
where and group by ( default is 1 )
, LAG(SAL,0) OVER ( ORDER BY EMPNO DESC ) LAG_0_SAL -- same as sal
, LAG(SAL,1) OVER ( ORDER BY EMPNO DESC ) LAG_1_SAL -- prior row value
, LAG(SAL,2) OVER ( ORDER BY EMPNO DESC ) LAG_2_SAL -- two row prior value
, COUNT(SAL)
, AVG(SAL)
FROM EMP
GROUP BY EMPNO , ENAME , SAL
;
EMPNO, ENAME, SAL, LEAD_SAL, LAG_0_SAL, LAG_1_SAL, LAG_2_SAL, COUNT(SAL),
AVG(SAL)
7934 MILLER 1300 3000 1300 NULL NULL 1
1300
7902 FORD 3000 950 3000 1300 NULL 1
3000
7900 JAMES 950 1100 950 3000 1300 1
950
7876 ADAMS 1100 1500 1100 950 3000 1 1100
7844 TURNER 1500 5000 1500 1100 950 1
1500
7839 KING 5000 3000 5000 1500 1100 1
5000
7788 SCOTT 3000 3000 3000 5000 1500 1
3000
7782 CLARK 3000 800 3000 3000 5000 1 3000
7369 SMITH 800 NULL 800 3000 3000 1
800

---------------------------------------------------------------------------------

SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS ename


FROM emp
GROUP BY deptno; -- is required as listagg is an aggregate function.

DEPTNO , ENAME
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

---------------------------------------------------------------------------------

select emp.* , nvl(comm,0), nvl2(comm,0,1) , COALESCE(comm,0) from emp

comm nvl nvl2


null 0 1
200 200 0

-- COALESCE (expr1, expr2) is same as


--CASE WHEN expr1 IS NOT NULL THEN expr1 ELSE expr2 END

---------------------------------------------------------------------------------

always check the requirement so to decide whetere to user row-number() function or


Rank() or Dense_Rank() function.

RANK() OVER (PARTITION BY deptno ORDER BY sal) AS myrank

7900 30 950 1
7654 30 1250 2
7521 30 1250 2
7844 30 1500 4

DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal) AS myrank

7900 30 950 1
7654 30 1250 2
7521 30 1250 2
7844 30 1500 3

---------------------------------------------------------------------------------

The FIRST and LAST functions can be used to return the first or last value from an
ordered sequence,

select empno , deptno , sal


, MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS
lowest -- no need of group by as this will always return scalar value.
, MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) AS
highest
from emp
where deptno = 30
empno deptno sal lowest highest
7900 30 950 950 2850
7654 30 1250 950 2850
7521 30 1250 950 2850
7844 30 1500 950 2850
7499 30 1600 950 2850
7698 30 2850 950 2850

---------------------------------------------------------------------------------

select RANK(1000, 500) WITHIN GROUP (ORDER BY salary, bonus)


from employees;

Will list employee rank for salary = 1000 and bonus = 500
example :
Rank
--------------
4

---------------------------------------------------------------------------------

-- generate sequentional numbers :

SELECT level
FROM dual
CONNECT BY level <= 10;

1
2
3

--generate date in range :


SELECT level , sysdate
, sysdate + level
, to_date('01-jan-2019','dd=mon-yyyy') + level
FROM dual
CONNECT BY level <= 10;

---------------------------------------------------------------------------------

SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY; -- Row Limiting Clause (12c onward)

VAL
----------
10
10
9
9
8

5 rows selected.

---------------------------------------------------------------------------------
generatingeven and odd numbers
---------------------------------------------------------------------------------

select level
, case when mod(level,2) <> 0 then 'YES' else 'NO' end as odd_number
, case when mod(level,2) = 0 then 'YES' else 'NO' end as even_number
, sum(level) over()
from dual
connect by level <=10

You might also like