Guide me with this stored procedure or function - sql

Manager | Employee |HireDate
----------------------------------------
ManagerA| EmpA |1/1/2012
managerA| EmpB |1/15/2012
ManagerB| Emp C |2/1/2012
ManagerA| Emp D |2/15/2012
ManagerB| Emp E |2/8/2012
The bonus amount for each manager is calculated based on how many recruits were hired that month.
ex. each Manager gets 1000 for first hire and 500 additional for every next.
Its almost like each record has a seed
Manager | Employee |HireDate | Seed
------------------------------------------------
ManagerA| EmpA |1/1/2012 | 1
managerA| EmpB |1/15/2012 | 2
ManagerB| Emp C |2/1/2012 | 1
ManagerA| Emp D |2/15/2012 | 1
ManagerB| Emp E |2/8/2012 | 2
and Bonus is a function of the seed as 1000+(seed-1)*500
I need help generating the seed .I am not sure if I should use a stored procedure to generate the seed or a function
eventually I want to generate a table as below
Manager | Employee |HireDate | Bonus
-------------------------------------------------
ManagerA| EmpA |1/1/2012 | 1000
managerA| EmpB |1/15/2012 | 1500
ManagerB| Emp C |2/1/2012 | 1000
ManagerA| Emp D |2/15/2012 | 1000
ManagerB| Emp E |2/8/2012 | 1500

To get the seed
Select
*
,ROW_NUMBER() Over(Partition By Manager, Year(HireDate), Month(HireDate) Order By HireDate) As Seed
From
YourTable
To get the bonus directly
Select
*
,1000 + (Seed - 1) * 500 As Bonus
From
(
Select
*
,ROW_NUMBER() Over(Partition By Manager, Year(HireDate), Month(HireDate) Order By HireDate) As Seed
From
YourTable
) T

Related

Leetcode problem: Department Highest Salary

The Employee table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id.
+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
The Department table holds all departments of the company.
+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, your SQL query should return the following rows (order of rows does not matter).
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
My solution is below, Someone please tell me why this is not working
Select Department , Employee ,MAX(Salary) AS SALARY FROM
(select Department.Name AS Department,Employee.Name as Employee, SALARY from employee
LEFT JOIN Department
ON Employee.DepartmentID=Department.ID) as base
GROUP BY Department
The difference between my code output and expected output is given below.
Output
{"headers": ["Department", "Employee", "SALARY"], "values": [["IT", "Joe", 90000], ["Sales", "Henry", 80000]]}
Expected
{"headers": ["Department", "Employee", "Salary"], "values": [["IT", "Jim", 90000], ["Sales", "Henry", 80000], ["IT", "Max", 90000]]}
Someone please tell me why this is not working
Because what you have so far reads like this: "for every department, return an unspecified employee, and also return max salary within this department". Note that max salary is in no way related to the employee that is returned. In this case, it's seems to be returning the first employee for each department. And in case of "Sales", it even turns out to be correct, accidentally.
What you should have written is "for every department, find out its max salary. Then find all employees whose salary is equal to max_salary for their department"
You first need to get the MAX(SALARY) by Department and then query all employee that have this salary in this department.
-- max salary by department, adding DepartmentName to the result
WITH max_salary as (
SELECT Department.DepartmentId, Department.Name as DptName, MAX(SALARY)
FROM Employee JOIN Department
ON Employee.DepartmentID=Department.ID
GROUP BY DepartmentId, Name
)
-- select ALL employees with max salary
SELECT DptName, e.Name, e.SALARY
FROM Employee e JOIN max_salary m
ON e.SALARY=m.SALARY AND e.DepartmentId=m.DepartmentId
Get the highest SALARY for each department, and then return the employees whose salaries are equal to the maximum SALARY. The following query does this.
WITH TB_Salary as (
SELECT MAX(SALARY) AS Salary,DepartmentId
FROM employee
GROUP BY DepartmentId
)
SELECT DISTINCT Department.Name AS Department,employee.Name AS Employee,employee.Salary FROM employee
JOIN TB_Salary ON employee.SALARY = TB_Salary.SALARY AND employee.DepartmentId = TB_Salary.DepartmentId
JOIN Department ON Department.Id = employee.DepartmentId
ORDER BY employee.Salary DESC
OR
SELECT DISTINCT Department.Name AS Department,employee.Name AS Employee,employee.Salary
FROM employee
JOIN
(
SELECT MAX(SALARY) AS Salary,DepartmentId
FROM employee
GROUP BY DepartmentId
) TB_Salary
ON employee.SALARY = TB_Salary.SALARY AND employee.DepartmentId = TB_Salary.DepartmentId
JOIN Department ON Department.Id = employee.DepartmentId
ORDER BY employee.Salary DESC
output:

SQL query with correlated subquery in where clause

I am fighting with a SQL.
The task is to write max(EMP.SAL) for each project (PROJ_EMP.PROJNO)
I have 3 tables.
Table PROJ which keep data about projects:
PROJ.PROJNO | PROJ.NAME
------------+-------------
1 | PROJECT1
2 | PROJECT2
3 | PROJECT3
Table EMP for employees data:
EMP.EMPNO | EMP.NAME | EMP.SALARY
----------+----------+------------
1000 | name1 | 4000
1001 | name2 | 2000
1002 | name3 | 3000
1003 | name4 | 6000
1004 | name5 | 1000
And Table PROJ_EMP for connecting these projects with employees:
PROJ_EMP.EMPNO | PROJ_EMP.PROJNO
---------------+----------------
1000 | 1
1001 | 1
1002 | 2
1003 | 2
1004 | 3
Such I mentioned at the beginning post: I am trying to write max(EMP.SAL)for each project using a correlated subquery in where clause so the desired result should be:
PROJ_EMP.PROJNO | EMP.EMPNO | EMP.SAL
----------------+-----------+---------
1 | 1000 | 4000
2 | 1003 | 6000
3 | 1004 | 1000
I don't have any working result however my SQL query closed to aim looks:
SELECT EMP.EMPNO, EMP.SAL, PROJ_EMP.PROJNO
FROM EMP, PROJ_EMP
WHERE EMP.EMPNO = PROJ_EMP.EMPNO
AND EMP.SAL = (SELECT MAX(EMP.SAL)
FROM EMP, PROJ_EMP p_e
WHERE EMP.EMPNO = PROJ_EMP.EMPNO
AND PROJ_EMP.PROJNO = p_e.PROJNO)
GROUP BY
PROJ_EMP.PROJNO, EMP.SAL, EMP.EMPNO
ORDER BY
PROJ_EMP.PROJNO, EMP.SAL DESC
By the result are not like I expected. Can you help me? Thank you fo any help in advance
Learn to use proper, explicit, standard JOIN syntax. I think you are trying to write:
SELECT e.EMPNO, e.SAL, pe.PROJNO
FROM EMP e JOIN
PROJ_EMP pe
ON e.EMPNO = pe.EMPNO
WHERE EMP.SAL = (SELECT MAX(EMP.SAL)
FROM EMP e2 JOIN
PROJ_EMP pe2
ON e2.EMPNO = pe2.EMPNO
WHERE pe2.PROJNO = pe.PROJNO
)
ORDER BY pe.PROJNO, e.SAL DESC ;
You can apply inner join among three tables and filter by max analytic function partitioned by project number and ordered by descending salary to determine the max salaries for each project number :
select projno, empno, salary
from
(
select p.projno, e.empno, e.salary,
max(e.salary) over (partition by p.projno order by e.salary desc) as max_salary
from proj p
join proj_emp pe on pe.projno = p.projno
join emp e on e.empno = pe.empno
)
where salary = max_salary;
Demo

Oracle SQL: Divided one row to other row in other table without repatriation depending in variable value

I have tow table :
Customer :
name
-----
TOMMY
LOUIE
HUGO
OLLIE
DAVID
LEWIS
JACKSON
Employees :
name | stage
---------+---------
OLIVER | 1
NOAH | 1
ALFIE | 1
OSCAR | 2
NOAH | 2
OLIVER | 2
LEO | 2
In Employee I have two stages. In each stage can it have same employees or different, what I want to divide or distribute the customer to employee with two condition :
the customer in first stage must have different employee in second stage
each employee must have same number of customer in each stage and each customer must have 1 employee in each stage without repetition.
I have done the procedure with cursor that insert the result in different table but the problem it give wrong result that repeating the customer in stage 1 to the same employee in stage 2 (e.g NOAH take the same Customer )
CREATE PROCEDURE AUDIT_Customer AS
CURSOR Customer_STAGE1 IS SELECT * FROM (
select
s.name Customer_name
,t.name Employees_name
from (select name, row_number() over(order by name) as rn from Employees WHERE stage = 1 ) t
join (select name, row_number() over(order by name) as rn from Customer ) s
on mod(s.rn - 1, (select count(*) from Employees WHERE stage = 1)) = t.rn -1);
CURSOR Customer_STAGE2 IS SELECT * FROM (
select
s.name Customer_name
,t.name Employees_name
from (select name, row_number() over(order by name) as rn from Employees WHERE stage = 2 ) t
join (select name, row_number() over(order by name) as rn from Customer ) s
on mod(s.rn - 1, (select count(*) from Employees WHERE stage = 2)) = t.rn -1);
Begin
For y in Customer_STAGE1 Loop
Insert into Customer_Employee(Customer_name,Employees_name,RECIVE_DATE,stage)
Values (Y.Customer_name ,Y.Employees_name,sysdate,1) ;
End Loop ;
For y in Customer_STAGE2 Loop
Insert into Customer_Employee(Customer_name,Employees_name,RECIVE_DATE,stage)
Values (Y.Customer_name ,Y.Employees_name,sysdate,2) ;
End Loop ;
COMMIT;
End AUDIT_Customer;
the results :
Customer| Employees| stage
--------+--------- +---------
TOMMY | OLIVER | 1
LOUIE | OLIVER | 1
HUGO | NOAH | 1
OLLIE | NOAH | 1
DAVID | ALFIE | 1
LEWIS | ALFIE | 1
JACKSON | ALFIE | 1
TOMMY | OSCAR | 2
LOUIE | OSCAR | 2
HUGO | NOAH | 2
OLLIE | NOAH | 2
DAVID | OLIVER | 2
LEWIS | OLIVER | 2
JACKSON | LEO | 2
how i can solve it?
filter the second section of your procedure
this might help:
(select name, row_number() over(order by name) as rn from Employees WHERE stage = 2 and Employee.Name not in (select Employee.Name from Employee WHERE stage = 1))

Kindly help to write SQL queries

I need your help to write two SQL queries (DB Oracle) to fetch data. Both table has huge data so need to take care of the performance also. Below is the scenario -
There are two tables Department (DEPT) and Employee (EMP). They have a 1 (DEPT) : M (EMP) relationship.
Department table has columns
Row_id, DeptNm, Created_date
Employee table has columns
Row_id, EMPName, Emp_num, Par_row_id (FK to DEPT.row_Id), Salary
For a specific Department, sort data per employee's decreasing salary and rank it. Data should be shown like this:
DeptNm | EmpNm | Salary | Rank
--------------------------------
Finance | Vikram | 200000 | 1
Finance | Uttaam | 150000 | 2
Finance | Rajeev | 100000 | 3
ITDPPT | Balaajii | 150000 | 1
ITDEPT | Harsha | 120000 | 2
ITDEPT | Weeniji | 100000 | 3
Query that to show the data highest salary for a department. Data should be as -
Dept_Nm | EMP_NM | Salary
Finance | Vikramadit | 2000000
ITDEPT | Balaji | 1500000
select *
from (
select dp.deptname,
emp.empname,
emp.salary,
dense_rank() over (partition by dp.deptname order by emp.salary desc) as rnk
from employee emp
join department dp on dp.row_id = emp.par_row_id
) t
where rnk = 1
Try this will help you please put Rank as I didn't get what process you want if you want dynamic Rank than try any "temp" variable.
select D.DeptName,E.EmpName,E.Salary from Employee E
lefe join Department as D on D.Par_Row_Id=E.Row_Id order by E.Salaray DESC
select D.DeptName,E.EmpName,E.Salary from Employee E
left join Department as D on D.Par_Row_Id=E.Row_Id order by E.Salaray DESC

Return name of the employee who having top salary with join

here is the situation. I have two tables, one is table Tbl_employ, second is tbl_details.
Tbl_employ
----------
id | name
1 | Ravi
2 | ram
3 | sham
4 | john
Tbl_details
-----------
id | salary | emp_id
1 | 500 | 1
2 | 200 | 2
3 | 400 | 3
4 | 501 | 4
I want to return the name of the employee who has top salary in tbl_detail.
What will be the join query for this condition?
Please suggest. Thanks in advance.
Perhaps:
SELECT TOP(1) name
FROM Tbl_employ e INNER JOIN Tbl_details d ON e.id = d.emp_id
ORDER BY d.salary DESC;
Essentially, this joins the two tables on the key fields (id and emp_id), returning only a single result (TOP(1)) that is the maximum salary row (ORDER BY d.salary DESC).
I appreciate the answer of #Max Vernon.
You can also do it by another way. Please try this
select t.name from (
select Distinct top 1 salary ,name
from Tbl_employ as E
left outer join Tbl_details as D on D.empid=E.id
order by salary desc
) as t
you can check it here SQL Fiddle