SQL GROUP BY FirstName, Lastname and Year - sql

I have made the query below=>
SELECT FirstName,
LastName,
COUNT(*) AantalBestellingen,
YEAR(Orders.OrderDate) as Jaar
from Employees
RIGHT JOIN Orders ON (Employees.EmployeeID=Orders.EmployeeID)
WHERE Employees.ReportsTo IS NOT NULL
GROUP BY Employees.FirstName, Employees.LastName, YEAR (Orders.OrderDate)
ORDER BY YEAR (Orders.OrderDate)
I need to select the first name, lastname from the employees and the total orders they have processed within the last year.
After adding the group by year to the query it's not showing the unique employees anymore but it shows the years. I need to get only the unique employees and the last order year they have processed an order in.
Any advice what i'm doing wrong?

One way to do this is with an inner select:
SELECT
FirstName,
LastName,
COUNT(*) as AantalBestellingen,
(select YEAR(max(Orders.OrderDate)) from Orders O
where Employees.EmployeeID=O.EmployeeID) as Jaar
from
Employees
RIGHT JOIN Orders
ON (Employees.EmployeeID=Orders.EmployeeID)
WHERE
Employees.ReportsTo IS NOT NULL
GROUP BY
Employees.FirstName,
Employees.LastName
ORDER BY Jaar

You can place the Last Year condition in WHERE clause as follows
SELECT FirstName,
LastName,
COUNT(*) AantalBestellingen,
from Employees
RIGHT JOIN Orders ON (Employees.EmployeeID=Orders.EmployeeID)
WHERE Employees.ReportsTo IS NOT NULL AND YEAR(Orders.OrderDate) = 2014
GROUP BY Employees.FirstName, Employees.LastName

Can you try this one... This will give all employee, his only last year order count and last year.
;with cteMaxYear as
(select max(YEAR(Orders.OrderDate)) MaxOrderYear, EmployeeID
from Orders
group by EmployeeID)
SELECT FirstName,
LastName,
COUNT(*) AantalBestellingen,
m.MaxOrderYear as Jaar
from Employees e
left outer join cteMaxYear m
inner join Orders o ON m.EmployeeID=o.EmployeeID and m.MaxOrderYear=o.YEAR(Orders.OrderDate)
on e.EmployeeID = m.EmployeeID
WHERE e.ReportsTo IS NOT NULL
GROUP BY e.FirstName, e.LastName, m.MaxOrderYear
ORDER BY m.MaxOrderYear

Related

Exclude column from resultset if subquery returns null

I'm trying to figure out how/if there is a way to exclude a column from the final resultset if the results of a sub-query are null.
What I'm trying to achieve is something like below.
If there is a consultant you'd get as a resultset:
firstName, lastName, department, consultant
If there is NO consultant you'd get as a resultset:
firstName, lastName, department
My query is currently:
SELECT
firstName,
lastName,
department,
(
SELECT consultantName
FROM consultants c
INNER JOIN employees e c.userId = e.userId
)
FROM employees
ORDER BY department,lastName
How can this be done?
The number of columns will not change depending on the resultset, so you will always have 4 columns.
What you can do is a LEFT JOIN that will fill the Consultant column with NULL when no items are a match
SELECT
e.firstName,
e.lastName,
e.department,
c.consultantName
FROM employees e
LEFT join consultants c
on e.userId = c.userId
ORDER BY department,lastName
In the case you want two different resultset, you can write two queries :
Return 3 columns only for when the consultant doesn't exist
SELECT
e.firstName,
e.lastName,
e.department,
FROM employees e
WHERE userId not in
(
select userId from consultants
)
ORDER BY department,lastName
Return 4 columns when there is a match
SELECT
e.firstName,
e.lastName,
e.department,
c.consultantName
FROM employees e
INNER JOIN consultants c
on e.userId = c.userId
ORDER BY department,lastName

Calculate SUM from one table and display columns from another

I have 2 tables, Employee, and Transaction
Transaction
tID
cID
carID
eID
tDate
PickupDate
ReturnDate
Amount_Due
Employee
eID
fName
lName
Job
Manager
Hired
I need to calculate the commission (2.5%) and display that along with fName and lName.
I've calculated the commission, I think I've done the join correctly but can't quite figure out how to add in a SELECT to show the other two columns.
SELECT t.Amount_Due
, SUM(t.Amount_Due*0.025) AS Commission
FROM [Transaction] t
JOIN Employee e ON t.eID = e.eID
GROUP BY t.Amount_Due
You are grouping by the wrong columns, and you are trying to select Amount_Due and aggregate it at the same time:
SELECT e.fName
, e.lName,
, SUM(t.Amount_Due * 0.025) AS Commission
FROM [Transaction] t
JOIN Employee e
ON t.eID = e.eID
GROUP BY e.ID, e.fName, e.lName;
Probably just a typo - the JOIN should probably be ON t.eID = e.eId. You need to include both tables (table aliases) involved - you're currently just using the t.eID twice.
Try this :
SELECT
t.Amount_Due, SUM(t.Amount_Due*0.025) AS Commission
FROM
[Transaction] t
JOIN
Employee e ON t.eID = e.eID
GROUP BY
t.Amount_Due
As pointed out by #charlieface - it seems very odd that you're summing the Amount_due, and at the same time trying to group by that same column..... my best guess is that you probably want to group by the employee, based on their eID - so use something like this:
SELECT
e.eID, e.fName, e.lName, SUM(t.Amount_Due*0.025) AS Commission
FROM
[Transaction] t
JOIN
Employee e ON t.eID = e.eID
GROUP BY
e.eID, e.fName, e.lName
for that.

Write a query to display the name of the department that has the maximum student count

this is the schema Write a query to display the name of the department that has the maximum student count.
this is what is tried.
select d.department_name,count(s.student_id)
from department d left join student s
on d.department_id=s.department_id
group by d.department_name,d.department_id
order by d.department_name;
and i think there is something missing in my code
You're almost there.
Order the result in descending order on the number of students and then take the first row:
SELECT department_name
FROM
(
SELECT d.department_name,
COUNT(*) AS nr_students
FROM department d
JOIN student s
ON d.department_id = s.department_id
GROUP BY d.department_name
ORDER BY nr_students DESC
)
WHERE ROWNUM <= 1;
Based on the schema mentioned, you would have to make a join (INNER JOIN) to the department table from the staff table to get the name of the department.
If the name of the department is not desired and the counts can just be based on the department_id, then a join is not required.
The queries for both the scenarios is mentioned below.
Oracle SQL query for result with the department name, i.e. with INNER JOIN
SELECT D.DEPARTMENT_NAME, COUNT(S.DEPARTMENT_ID) AS STAFF_COUNT FROM **DEPARTMENT D, STAFF S** --INDICATES INNER JOIN IN ORACLE SQL
WHERE D.DEPARTMENT_ID = S.DEPARTMENT_ID
GROUP BY D.DEPARTMENT_NAME
ORDER BY STAFF_COUNT DESC
Oracle SQL query for result without the department name, just the department_id
SELECT S.DEPARTMENT_ID,COUNT(S.DEPARTMENT_ID) AS STAFF_COUNT FROM STAFF S
GROUP BY S.DEPARTMENT_ID
ORDER BY STAFF_COUNT DESC
Hope this helps. Cheers.
I tried this and it worked.
select department_name
from department d inner join student s
on s.department_id=d.department_id
having count(*) in (
select max(count(student_id))
from student s join department d
on d.department_id=s.department_id
group by d.department_id)
group by d.department_id,department_name;
Select * from (
SELECT D.DEPARTMENT_NAME, COUNT(S.DEPARTMENT_ID) AS STAFF_COUNT
FROM DEPARTMENT D, STAFF S
WHERE D.DEPARTMENT_ID = S.DEPARTMENT_ID
GROUP BY D.DEPARTMENT_NAME
ORDER BY STAFF_COUNT DESC)
where rownum=1;
This query will give department name that has maximum number of student count

How do I count something the number of employee that is in a different table in SQL?

The question asks
"Write a query to display the city and country where an office is located and a count of the number of employees at that location. Order the results in descending order of the number of employees."
So far I have put,
SELECT city, country, SELECT COUNT(city,country)
FROM Offices
ORDER BY(SELECT COUNT(city,country)
FROM Offices)DESC;
It wont let me run it however. I reckon I made a mistake in the SELECT COUNT part.
The employees table contains
employeeNumber
lastName
firstName
extension
email
reportsTo
jobTitle
officeCode
The Office table contains
officeCode
city
phone
addressLine1
addressLine2
state
country
postalCode
territory
officeLocation
Anyone know what I'm doing incorrectly? Thank you! Sorry if this is a lot of stuff.
You can do it using a LEFT JOIN, GROUP BY and ORDER BY.
We need LEFT JOIN and GROUP BY to get the employee count and the ORDER BY to order the results in descending order of no of employees.
SELECT OfficeCode, City, Country, COUNT(E.employeeNumber) AS EmployeeCount
FROM Offices O
LEFT JOIN Employees E ON E.OfficeCode = E.OfficeCode
GROUP BY OfficeCode, City, Country
ORDER BY COUNT(E.employeeNumber) DESC
use join and count
SELECT city, country,officeLocation, COUNT(e.employeeNumber)
FROM Offices ofc join employees e on ofc.officeCode=e.officeCode
group by city, country,officeLocation
A couple ways to tackle this. Using a LEFT OUTER JOIN: (make sure to use a LEFT OUTER and not an INNER JOIN here or else you will only get locations with employees. That may work in your case but what if a location has no current employees?)
SELECT City, Country, COUNT(e.employeeNumber) AS EmployeeCount
FROM Offices o
LEFT OUTER JOIN Employees e
ON e.OfficeCode = o.OfficeCode
GROUP BY City, Country
ORDER BY 3 DESC
Or you could use a subquery with the select statement:
SELECT City, Country,
(SELECT COUNT(*) FROM Employees e WHERE o.OfficeCode = e.OfficeCode) AS EmployeeCount
FROM Offices o
ORDER BY 3 DESC

Northwind - List of top ten employees

I have another trouble with my SQL queries.
My task is to create a list of top 10 employees, with the most sales in 1997.
So far I have this, simple query that shows me list of employees and which order they've sold.
SELECT
Orders.EmployeeID,
Orders.OrderID
FROM
Employees
JOIN
Orders ON Orders.EmployeeID = Employees.EmployeeID
ORDER BY
Orders.EmployeeID;
Now I want to group up those numbers, I need to know how many sales each employee did in 1997. How to do that?
You can get the results that you need without JOIN and GROUP BY if you order by results of a subquery:
SELECT TOP 10 *
FROM Employees e
ORDER BY (
SELECT COUNT(*)
FROM Sales s
WHERE s.EmployeeId=e.EmployeeId
AND DATEPART(year, o.OrderDate)=1997
) DESC
This yields top ten employees by the number of sales transactions.
If you need anything from Sales, say, the count, you would need to go the GROUP BY route:
SELECT TOP 10 * FROM (
SELECT e.EmployeeId, COUNT(*) AS SalesCount
FROM Employees e
LEFT OUTER JOIN Orders o ON o.EmployeeId=e.EmployeeId
AND DATEPART(year, o.OrderDate)=1997
GROUP BY e.EmployeeId
) groups
ORDER BY SalesCount DESC
WITH CTE AS
(
SELECT EmployeeId,COUNT(*) as cn,
DENSE_RANK(ORDER BY COUNT(*) DESC) AS rn
FROM orders
WHERE DATEPART(year,OrderDate)=1997
GROUP BY EmployeeId
)
SELECT e.*,COALESCE(o.cn,0) AS CountOrders
FROM Employees e
LEFT JOIN CTE o
ON e.EmployeeId=o.EmployeeId
WHERE o.rn<=10
It can reduce to this
SELECT top(10) EmployeeID, count(*) as cnt
FROM Orders
group by EmployeeID
ORDER BY count(*) desc;