SQL to fetch least 2 salaries from a table department wise - sql

How would be the SQL to fetch least 2 salaries from a table department wise ?
Sample Table:
empid salary Dept
---------------------
101 2000 aaa
102 1000 bbb
103 5000 bbb
104 8000 ccc
105 3000 aaa
106 4000 aaa
107 6000 ccc
108 7000 bbb
109 9000 ccc
Output should be like:
Dept empid salary
----------------------
aaa 101 2000
aaa 105 3000
bbb 102 1000
bbb 103 5000
ccc 104 6000
ccc 107 8000

SELECT
t.dept
,t.empid
,t.salary
FROM
#test t
WHERE
t.empid IN (
SELECT TOP 2
empid
FROM
#test
WHERE
dept = t.dept
ORDER BY
salary
)
ORDER BY
dept,empid
As was pointed out, there may be other people in dept ccc with a salary of 8000 that will be missed.

Following this blog post and supposing the table name is "samptab":
select dept, empid, salary
from samptab
where (
select count(*) from samptab as s
where s.dept = samptab.dept and s.salary <= samptab.salary
) <= 2 order by dept;
You can change the number "2" in the query row if you want more or less rows.

Related

finding manager id from employee table

I have a table data like in the below.
Emp_id Emp_name Dept_id
111 aaa 1
222 bbb 2
333 ccc 3
444 ddd 4
555 eee 5
Then i want to populate new column manager id as next emp_id from the employee table like in the below.
Emp_id Emp_name Dept_id Manager_id
111 aaa 1 222
222 bbb 2 333
333 ccc 3 444
444 ddd 4 555
555 eee 5 111
Thanks for your help in advance!
You can return the value as:
select t.*,
coalesce(lead(empid) over (order by empid),
min(empid) over ()
) as manager_id
from t;
Perhaps a select query is sufficient. Actually modifying the table is a bit tricky and the best syntax depends on the database.

Need to pick up the SUM OF Tax Amount for the highest Sequence number Per Year, Per SSN, Per employer

Consider Employee table:
Employerid ssn year Seqnumber q1taxamt q2taxamt q3taxamt q4taxamt
1004 101 2013 1 2000 0 0 0
1004 101 2013 2 2000 100 0 0
1004 101 2013 3 2000 100 200 0
1004 101 2013 4 2000 100 200 300
1004 102 2013 1 3000 0 0 0
1004 102 2013 2 3000 200 0 0
1004 102 2013 3 3000 200 300 0
1004 102 2013 4 3000 200 300 400
1004 102 2013 5 3000 200 300 400
Here the transformation rule is we need to pick the highest Seqnumber with respect to each ssn per year per
Employerid and the amounts.
i.e for 10004 for sum(q1taxamt) is 2000 +3000 = 5000
The Logic is ssn 101 has highest seq number of 4 and ssn 102 has highest seq number of 5 so we need to pick those values wrt to employerid
Example:
Want to check for q1taxamt: 2000 +3000 = 5000
Want to check for q4taxamt: 300 +400 = 700
output must be:
Employerid YEAR q1taxamt q2taxamt q3taxamt q4taxamt
10004 2013 5000 300 500 700
The below query is generating wrong result:
Select
Sum(E1.q1taxamt) q1taxamt,
Sum(E1.q2taxamt) q2taxamt,
Sum(E1.q3taxamt) q3taxamt,
Sum(E1.q4taxamt) q4taxamt,
E1.Employerid,
E1.YEAR
from Employee E1
join
(
select
E.Employerid,
MAX(E.seqnumber) seqnumber,
E.YEAR
from Employee E
group by E.Employerid,E.SSn,E.year
)E2
on E1.Employerid=E2.Employerid
AND E1.YEAR=E2.YEAR
and E1.seqnumber=E2.Taxseqnumber
Just use row_number():
select e.*
from (select e.*,
row_number() over (partition by E.Employerid, E.SSn, E.year
order by e.seqnumber desc
) as seqnum
from Employee e
) e
where seqnum = 1;
For best performance, you want an index on Employee(EmployerId, SSN, seqnumber desc).
You missing SSN join predicate between E1 and E2 thats why you are getting wrong result. I think this might be faster than Row_Number method.
Select
Sum(E1.q1taxamt) q1taxamt,
Sum(E1.q2taxamt) q2taxamt,
Sum(E1.q3taxamt) q3taxamt,
Sum(E1.q4taxamt) q4taxamt,
E1.Employerid,
E1.YEAR
from Employee E1
join
(
select
E.Employerid,
E.SSn,
MAX(E.seqnumber) seqnumber,
E.YEAR
from Employee E
group by E.Employerid,E.SSn,E.year
)E2
on E1.Employerid=E2.Employerid
AND E1.YEAR=E2.YEAR
AND E1.SSN = E2.SSN --Here
and E1.seqnumber=E2.Taxseqnumber

Select statement with multiple rows from condition on values in single column affecting more than one column

I have the table below.Using salary as condition I want to get multiple rows. Below is current table call it employee.
empid | name | salary
-----------------------------------
1 A1 alex 20000
2 B2 ben 4500
3 C1 carl 14000
compare the salary to certain fixed values, and every time the salary is larger than the fixed value, show a record in output.Also output a calculated tax column.Below is a step closer to my final result
select e.*,tax= (case when salary<6000 then tax=0.06 *salary,when salary between 6000 and 18000 then tax= 0.06 *(salary -6000),else tax =0 ),m.incometype,
from employee e
left join
(
select 0 as threshold, 101 as incometype
union
select 5999 as threshold, 102 as incometype
union
select 17999 as threshold, 103 as incometype
) m
on e.salary > m.threshold
order by e.empid
Desired ouput would be:
empid | name | salary | incometype | tax
----------------------------------------------
1 A1 alex 20000 101 360
2 A1 alex 20000 102 720
3 A! alex 20000 103 0
4 B2 ben 4500 101 270
5 C1 carl 14000 101 360
6 C1 carl 14000 102 480
this is a question further to Select statement with multiple rows from condition on values in single column
this may help you
select e.*,
case
when salary<6000 then (0.06*salary)
when salary between 6000 and 1800 then (0.06*(salary -6000))
when m.incometype=103 then 0
end as tax
,m.incometype,
from employee e
left join
(
select 0 as threshold, 101 as incometype
union
select 5999 as threshold, 102 as incometype
union
select 17999 as threshold, 103 as incometype
) m
on e.salary > m.threshold
order by e.empid

Oracle SQL Rollup Query : Determine the start of group

How can we determine the start of a Group in Rollup ?
And the include the group value by concatinating it with some useful text and display it as first row of the group ?
e.g:
dept emp_name sal
---- -------- ---
10 sac 999
10 abc 888
20 pqr 777
20 lmn 123
30 stv 444
30 com 555
o/p after rollup should be
dept emp_name sal
---- -------- ---
Department 10 NULL NULL
10 sac 999
10 abc 888
20 1887
Department 20 NULL NULL
20 pqr 777
20 lmn 123
20 900
Department 30 NULL NULL
30 stv 444
30 com 555
30 999
3786
Here is the query with which you can achieve the requirement. It uses GROUP BY ROLLUP
SELECT DISTINCT 1 AS rn,dept, CONCAT('Department ', dept) AS DeptDesc, NULL AS Sum
FROM your_table
UNION ALL
SELECT 2, dept, CAST(dept AS VARCHAR(10)), SUM(SAL)
FROM your_table
GROUP BY ROLLUP(dept, emp_name)
ORDER BY dept, rn, sum
Here is the code at SQL Fiddle

how to write this query from 2 tables

Hear no relation have 2 table
"employee Table"
columns
Empid Empname Salary Age
1 abc 2000 20
2 xyz 3000 26
3 ijk 4000 32
4 mno 5000 50
"Groupname" table
columns
Groupid Groupname Min Max
1 young 18 25
2 middle 26 35
3 old 36 60
then i need result using both tables
empid empname age group
1 abc 2000 20 young
2 xyz 3000 26 middle
3 ijk 4000 32 middle
4 mno 5000 50 old
select empid,empname, salary, grp.groupname from employee emp left
outer join groupname grp
on ( emp.age > grp.[min] and emp.age <
grp.[max])
Try this:
select Empid, Empname, Salary, Age,Groupname
from Employee,GroupNameTable
where Age between Min and max