Query top 2 salaries in each department
You can't reference a calculated column directly in the where
clause. Use a CTE or sub-query.
with cte as (
select a.Name, a.salary a.[Dept id], b.Dept_Name
, row_number() over (partition by b.[Dept Name] order by a.salary) as row_rank
from dbo.d as a
inner join dbo.e as b on a.[Dept id] = b.[Dept id]
)
select *
from cte
where row_rank < 3;
You don't need [dept id] from both tables as they are the same. Also its advised to alias your tables with a meaningful alias, not just a, b etc
mysql query To get the top two salary from each department
SELECT emp1.departid , emp1.salary
FROM Department emp1
WHERE (
SELECT COUNT(DISTINCT(emp2.salary))
FROM Department emp2
WHERE emp2.salary > emp1.salary and emp1.departid = emp2.departid ) in (0,1) group by emp1.departid , emp1.salary
I have tested this solution in sql server. But i think it will work in ms sql as well.
I want to query difference between first and second highest salary
Use the DENSE_RANK
(if you want highest two unique salary values) or ROW_NUMBER
(if you want the salary of the two highest earning people regardless of ties) analytic functions and then use conditional aggregation:
SELECT MAX( CASE WHEN sal_rank = 1 THEN sal END )
- MAX( CASE WHEN sal_rank = 2 THEN sal END ) AS sal_difference_ignore_ties,
MAX( CASE WHEN sal_rownum = 1 THEN sal END )
- MAX( CASE WHEN sal_rownum = 2 THEN sal END ) AS sal_difference_with_ties
FROM (
SELECT e.deptno,
e.sal,
DENSE_RANK() OVER ( ORDER BY e.sal DESC ) AS sal_rank,
ROW_NUMBER() OVER ( ORDER BY e.sal DESC ) AS sal_rownum
FROM emp e
INNER JOIN dept d
ON ( e.deptno = d.deptno )
WHERE d.loc = 'New York'
);
Which, for the sample data:
CREATE TABLE emp ( deptno, sal ) AS
SELECT 1, 2000 FROM DUAL UNION ALL
SELECT 1, 2000 FROM DUAL UNION ALL
SELECT 1, 1000 FROM DUAL UNION ALL
SELECT 1, 500 FROM DUAL UNION ALL
SELECT 1, 200 FROM DUAL UNION ALL
SELECT 2, 2000 FROM DUAL UNION ALL
SELECT 2, 1500 FROM DUAL UNION ALL
SELECT 2, 200 FROM DUAL UNION ALL
SELECT 2, 700 FROM DUAL;
CREATE TABLE dept ( deptno, loc ) AS
SELECT 1, 'New York' FROM DUAL UNION ALL
SELECT 2, 'Beijing' FROM DUAL;
Outputs:
SAL_DIFFERENCE_IGNORE_TIES | SAL_DIFFERENCE_WITH_TIES
-------------------------: | -----------------------:
1000 | 0
Or, if you want all the departments:
SELECT deptno,
MAX( CASE WHEN sal_rank = 1 THEN sal END )
- MAX( CASE WHEN sal_rank = 2 THEN sal END ) AS sal_difference_ignore_ties,
MAX( CASE WHEN sal_rownum = 1 THEN sal END )
- MAX( CASE WHEN sal_rownum = 2 THEN sal END ) AS sal_difference_with_ties
FROM (
SELECT e.deptno,
e.sal,
DENSE_RANK() OVER ( PARTITION BY e.deptno ORDER BY e.sal DESC ) AS sal_rank,
ROW_NUMBER() OVER ( PARTITION BY e.deptno ORDER BY e.sal DESC ) AS sal_rownum
FROM emp e
INNER JOIN dept d
ON ( e.deptno = d.deptno )
)
GROUP BY deptno;SELECT deptno,
MAX( CASE WHEN sal_rank = 1 THEN sal END )
- MAX( CASE WHEN sal_rank = 2 THEN sal END ) AS sal_difference_ignore_ties,
MAX( CASE WHEN sal_rownum = 1 THEN sal END )
- MAX( CASE WHEN sal_rownum = 2 THEN sal END ) AS sal_difference_with_ties
FROM (
SELECT e.deptno,
e.sal,
DENSE_RANK() OVER ( PARTITION BY e.deptno ORDER BY e.sal DESC ) AS sal_rank,
ROW_NUMBER() OVER ( PARTITION BY e.deptno ORDER BY e.sal DESC ) AS sal_rownum
FROM emp e
INNER JOIN dept d
ON ( e.deptno = d.deptno )
)
GROUP BY deptno;
Which outputs:
DEPTNO | SAL_DIFFERENCE_IGNORE_TIES | SAL_DIFFERENCE_WITH_TIES
-----: | -------------------------: | -----------------------:
1 | 1000 | 0
2 | 500 | 500
db<>fiddle here
How to get max salary in each dept from 2 tables - sql?
Join the tables and the query that returns the max salary for each department:
select
d.name_dep, e.person_name, t.salary
from Dep d inner join (
select id_dep, max(salary) salary
from Emp
group by id_dep
) t on t.id_dep = d.id_dep
inner join Emp e on e.id_dep = t.id_dep and e.salary = t.salary
See the demo.
Results:
| name_dep | person_name | salary |
| ----------- | ----------- | ------ |
| energy | borat | 300 |
| econ | erjan | 1600 |
| credit | sergey | 1000 |
| manufactury | lucy | 20 |
| retail | mike | 1200 |
Get difference in top 2 salary of employee from each department
You can give the following query a try:
SELECT Dept, MAX(Rank) AS Rank,
SUM(CASE
WHEN rnk = 1 THEN Sal
WHEN rnk = 2 THEN -Sal
ELSE 0
END) AS diff
FROM (
SELECT @rnk := IF(@dept = Dept, @rnk + 1,
IF(@dept := Dept, 1, 1)) AS rnk,
Dept, Sal, Rank
FROM emp
CROSS JOIN (SELECT @rnk := 0, @dept = '') AS vars
ORDER BY Dept, Rank DESC, Sal DESC) AS t
GROUP BY Dept
The query uses variables to assign a rank number to each record depending on Rank
and Sal
values. The outer query consumes the variable values and performs conditional aggregation to calculate the difference between the first and the second ranking records.
Demo here
Related Topics
Is It Possible for Me to Include a Sub Report in a Tablix Row That Is Grouped by an Id
Conversion Failed When Converting from a Character String to Uniqueidentifier Error in SQL Server
What Does a Caret (^) Do in a SQL Query
Average Difference Between Two Dates, Grouped by a Third Field
Oracle 11G: Default to Static Value When Query Returns Nothing
SQL Transform Crosstab Pivot Data
Which Orm Frameworks Will Build and Execute the SQL Ddl for You
Format Function Not Working in SQL Server 2008 R2
How to Escape Double Quotes Inside a SQL Fulltext 'Contains' Function
Merge Duplicate Temporal Records in Database
SQL Trigger After Insert Update Another Table with Conditions
How to Return Only 1 Row If Multiple Duplicate Rows and Still Return Rows That Are Not Duplicates
How to Remove Duplicate Rows Except One
Does SQL Server Optimize Dateadd Calculation in Select Query
Row Num Is Not Displaying Any Rows When Using Between Keyword