Anil Thakur Anil Thakur - 1 month ago 7
SQL Question

How to get second highest Salary of Account Department?

I having three tables like below -:

Create table #temp (id int, DepartmentName varchar(50))
insert into #temp (id,DepartmentName) values(1,'Account')
insert into #temp (id,DepartmentName) values(2,'IT')
select * from #temp

Create Table #temp1(customerid int, CustomerName varchar(50),DepartmentId int)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(1,'Anil',1)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(2,'Ankit',2)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(3,'Mandeep',1)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(4,'Rajesh',2)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(5,'Rohit',1)
Insert into #temp1(customerid,CustomerName,DepartmentId)values(6,'Sharma',0)

Create Table #temp2(customerid int, salary int)
insert into #temp2(customerid,salary)values(1,2000)
insert into #temp2(customerid,salary)values(3,2399)
insert into #temp2(customerid,salary)values(4,4000)
insert into #temp2(customerid,salary)values(2,4500)
insert into #temp2(customerid,salary)values(5,7000)


select max(t2.salary) ,t.CustomerName,t1.DepartmentName
from #temp1 t
left join #temp t1 on t1.id=t.DepartmentId
left join #temp2 t2 on t2.customerid=t.customerid
where DepartmentName='Account'
and salary<>(select max(tt2.salary) from #temp2 tt2
inner join #temp1 tt1 on tt1.customerid=tt2.customerid
inner join #temp tt on tt.id=tt1.DepartmentId
where tt.DepartmentName='Account')
group by CustomerName,DepartmentName


But not getting second highest salary with this, could please anybody help me with this, i am using max aggregate function in outer query but still getting all the salary of account department.

Answer

Use Dense_Rank

SELECT
     DepartmentName,
     CustomerName,
     salary
FROM
    (
    SELECT
        t.DepartmentName,
        DENSE_RANK() OVER( PARTITION BY id ORDER BY salary desc) rno,
        salary,
        t1.CustomerName
    FROM #temp t
    JOIN #temp1 t1
        ON t.id = t1.DepartmentId
    JOIN #temp2 t2
        ON t1.customerid = t2.customerid 
    where  t.DepartmentName='Account'
    ) a

WHERE rno = 2 

Update Modified Your Query with dense_rank since we can not perform group by with customer names.

SELECT salary,
       CustomerName,
       DepartmentName
FROM   (SELECT t2.salary,
               t.CustomerName,
               t1.DepartmentName,
               Dense_rank()
                 OVER(
                   partition BY DepartmentName
                   ORDER BY salary DESC) rno
        FROM   #temp1 t
               LEFT JOIN #temp t1
                      ON t1.id = t.DepartmentId
               LEFT JOIN #temp2 t2
                      ON t2.customerid = t.customerid
        WHERE  DepartmentName = 'Account'
               AND salary NOT IN (SELECT Max(tt2.salary)
                                  FROM   #temp2 tt2
                                         INNER JOIN #temp1 tt1
                                                 ON tt1.customerid = tt2.customerid
                                         INNER JOIN #temp tt
                                                 ON tt.id = tt1.DepartmentId
                                  WHERE  tt.DepartmentName = 'Account'))a
WHERE  rno = 1