I am trying to Select the name, email address that has the highest individual sale for the current month but for some reason my select statement won't return the right date or the highest amount. Any guidance or help on right direction would be appreciated
Select
FirstName, LastName,Email, SaleDate, Max(Total)as HighestTotal
From
Sale, Employee
where
month(SaleDate) = 12
Group by
SaleDate, FirstName, LastName, Email
Use TOP 1 with ORDER BY HighestTotal desc to get the highest individual sale for the given month
Also use proper INNER JOIN syntax to join two tables. Considering that both the tables have emp_id as common column
SELECT TOP 1 WITH ties E.FirstName,
E.LastName,
E.Email,
S.SaleDate,
S.Total AS HighestTotal
FROM Sale S
INNER JOIN Employee E
ON E.emp_id = S.Emp_id
WHERE Month(S.SaleDate) = 12
ORDER BY HighestTotal DESC
With Ties will bring more than one employee in case of tie in highest individual sale.
1) You have to add a condition for the current year:
where month( SaleDate) = 12 AND year(SaleDate) = 2015
2) You have to add ORDER BY to get the highest value:
ORDER BY HighestTotal DESC
LIMIT 1
Related
A SQL Server database has 2 tables:
Department: Id
Employee: Id, Department, Employee_Name, Date_Hired
I wanted to display maximum 2 employees hired the latest in 2021 per department
For example
The output should be
I have this SQL:
SELECT e.*
FROM Employee e
WHERE e.Date_Hired IN (SELECT e.Date_Hired
FROM Employee e
WHERE YEAR(e.Date_Hired) = 2021)
ORDER BY e.Date_Hired DESC
But it is displaying all 3 items from department 1.
Thanks in advance!
SELECT e.*
FROM Employee e,
(SELECT id,
Date_Hired,
row_number() OVER(PARTITION BY Department ORDER BY id DESC) AS rn
FROM Employee e
WHERE YEAR (e.Date_Hired) = 2021) sub
WHERE rn <= 2
and e.id = sub.id
ORDER by e.Date_Hired DESC
If your relation had integer rank numbers
describing each employee's position within a department,
then a simple WHERE clause could easily request the top K employees.
So you are looking for the rank query function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql?view=sql-server-ver16
The relationship among RANK, DENSE_RANK, and ROW_NUMBER is
perhaps more subtle than your unit tests and future maintainers
would care to consider.
I am working on a table that contains employee data. The table has historical employee records based on department and year as follows:
Now I want to consolidate records based on EmployeeId, Department and get the Min FromYear and Max ToYear like this:
I tried to use a query :
Select EmployeeId, Department, MIN(FromYear), MAX(ToYear)
from Employee
GROUP BY EmployeeId, Department
But this query fails for the employee with ID 3 as it returns me only 2 rows:
I have added a similar structure and query here: http://sqlfiddle.com/#!9/6f1e53/5
Any help would be highly appreciated!
This is a gaps-and-islands problem. Identify the islands using lag() and a cumulative sum. Then aggregate:
select employeeid, department, min(fromyear), max(toyear)
from (select e.*,
sum(case when prev_toyear >= fromyear - 1 then 0 else 1 end) over (partition by employeeid order by fromyear) as grp
from (select e.*,
lag(toyear) over (partition by employeeid, department order by fromyear) as prev_toyear
from employee e
) e
) e
group by employeeid, department, grp
order by employeeid, min(fromyear);
Here is a db<>fiddle.
you can use self join as well
select a.employeeid, min(a.fromyear), max(b.toyear) from emp a
inner join emp b on a.employeeid=b.employeeid
group by a.employeeid
I have two tables first one is Employee and second one is Salary.
Employee:
Salary:
This is the structure of both tables and I need to find the name of the person who has got highest salary in Feb 2014.
I tried by below Query but not getting correct output.
select first_name+' '+last_name as Name from Employee where
(select top(1)empid from Salary order by salary_amt desc)
Youcan just join the first and second table on empId. Use max(salary_amt) and make sure you add the date condition in your where clause as #Lamak mentioned
this should work:
select
empID,
first_name,
last_name,
sum(salary_amt) as salary_in_month
from
salary s
join employee e on s.empID=e.empID
where
month(salary_month)=2
and year(salary_month)=2014
group by empID
order by sum(salary_amt) desc
limit 1
select first_name+' '+last_name as Name
from Employee e
join Salary s
On s.EmpId = e.EmpId
and salary_Month = 'Feb 2014'
and cast(s.Salary_amt as money) =
(Select Max(cast(Salary_amt as money))
from salary
Where salary_Month = 'Feb 2014')
NOTE: There should be a unique alternate composite key on Salary.Salary_month and Salary.empId.
Thank you friends for your answers. I changed the data type of salary_amt to money and working answer is:
select top(1)first_name+' '+last_name as Name
from Employee e
join Salary s
On s.EmpId = e.EmpId
and salary_Month = 'Feb 2014' order by salary_amt desc
Empp has two columns = id,name
Salary has four columns = sal_id,id,sal,month
Let the given month be "jan"
SELECT E1.name, S1.sal FROM Empp E1 INNER JOIN salary S1 ON E1.id = S1.id where
S1.sal = (select max(S2.sal) from Salary S2
where S2.month='jan');
I have a employee and employee_history table. For every update on employee table, I insert a record into the employee_history table.
Both the tables have a column called as effective date which indicates that the employee status as on that effective date.
Below are my two tables.
I need to get the employee record latest as on that effective date.
e.g If I need to get the employee as on 16 may I should get the emp_hist_id = 2 record from history table. As on 5 june I should get the emp_hist_id = 4 from hist table.
And as on 15th August I should get the record from employee table itself.
Please help.
You could try something like
SELECT * FROM (
SELECT * FROM (
(SELECT emp_id, name, email, title, region, division, "effective date"
FROM employee
WHERE emp_id = desired_id)
UNION
(SELECT emp_id, name, email, title, region, division, "effective date"
FROM employee _history
WHERE emp_id = desired_id)
) t
WHERE t."effective date" <= desired_date
ORDER by t."effective date" DESC) p
WHERE ROWNUM = 1
The idea is to take records related to desired user from both tables, then take dates lower than desired one and finally catch the first
You can solve this problem without analytic functions. The subquery here calculates the most recent effective date in the history record before the employee effective date:
select e.*
from employee_history eh join
(select e.employee_id, max(eh.effective_date) as latest_effective_date
from employee e join
employee_history eh
on e.employee_id = eh.employee_id and
e.effective_date >= eh.effective_date
) ehl
on eh.employee_id = ehl.employee_id and
eh.effective_date = ehl.effective_date
This solution assumes that there are no duplicate effective dates in the history table. If there are, then you have another option. Assuming the employee_history_ids are assigned sequentially, take the max of that id instead of the date.
There are alternative formulations of the solution using Oracle's analytic functions.
Try the following :
SELECT *
FROM
(SELECT e.emp_id,
e.name,
e.email,
e.title,
e.region,
e.division,
e.effective_date,
row_number() over (partition BY e.emp_id
ORDER BY e.effective_date DESC) rn
FROM employee e
UNION ALL
SELECT eh.emp_id,
eh.name,
eh.email,
eh.title,
eh.region,
eh.division,
eh.effective_date,
row_number() over (partition BY eh.emp_id
ORDER BY eh.effective_date DESC) rn
FROM employee_history eh)
WHERE effective_date < to_date('15/06/2012','DD/MM/YYYY')
AND rn = 1
you can see a better example here
I want to find the largest sale for each of my employees (and display the name of the employee). In MySQL, it's pretty straightforward:
select *
from employee, sale
where employee.id = sale.employee_id
group by employee_id
order by sale.total desc
This does pretty much what one would expect, it would return a list of employees and end up returning the largest sale record with the employee row.
But, Oracle does not allow you to return columns which are not group by expressions when a group by clause is used. Do this make what I do in MySQL "impossible" in Oracle? Or is there some workaround? I suppose I could perform some sort of subquery, but not sure if there is another way to do this that wouldn't quite be so complicated to construct.
Get rid of your select * and replace it with just the columns you need and then group by all the "non-processed" columns.
You'll end up with something like:
select employee.id, employee.name, max(sale.total)
from employee, sale
where employee.id = sale.employee_id
group by employee.id, employee.name
order by max(sale.total) desc
It's a pain - I've had to do this many times before - but just add all the related columns to your group by
To get the largest sale you can use group by with the max function.
select e.name, max (s.total)
from employee e, sale s
where e.id = s.employee_id
group by e.name
order by s.total desc
I have made an assumption that the employee name is in the name column of the employee table. I have also aliased the employee table and sales tables.
If you would prefer to see the total sales for an employee, you can swap out max() and use sum() instead.
Congratulations, you've learned just enough to be dangerous!
What you really want is each employee's largest sale. Now it happens that sorting them by sales amount desc and then grouping them works in MySQL, even though that isn't legal according to ANSI SQL. (Basically, MySQL is arbitrarily grabbing the first row for each employee, and that "works" because of the sort.)
The right way to do this is not to rely on the side of effect of the sort doing what you want; instead you should explicitly ask for what you want: the largest sale for each employee. In SQL that's:
select employee.id, max( sale.total)
from employee, sale
where employee.id = sale.employee_id
group by employee.id
order by 2
If you want to select an employee with a highest sale, you don't need GROUP BY here at all.
All you need is to select the highest sale and join it back to the employees:
SELECT *
FROM (
SELECT sale.*, ROW_NUMBER() OVER (ORDER BY total DESC) AS rn
FROM sale
) s
JOIN employee e
ON e.id = s.employee_id
AND s.rn = 1
This will select a single row with a total highest sale.
If you want to select per-employee highest sale, just add a PARTITION BY clause to your query:
SELECT *
FROM (
SELECT sale.*, ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY total DESC) AS rn
FROM sale
) s
JOIN employee e
ON e.id = s.employee_id
AND s.rn = 1