I need to select employees' names from those who has sold products, for the biggest total sum of money in each of the years, in Northwind database. I've managed to create a valid query like this:
WITH TEMP_QUERY AS
(
SELECT DATEPART(YEAR, OrderDate) AS 'Year', FirstName + ' ' + LastName AS 'Employee', SUM(UnitPrice * Quantity) AS 'Total year sale' FROM Employees
INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
GROUP BY FirstName + ' ' + LastName, DATEPART(YEAR, OrderDate)
)
SELECT DATEPART(YEAR, OrderDate) AS 'Year', FirstName + ' ' + LastName AS 'Employee', SUM(UnitPrice * Quantity) AS 'Total year sale' FROM Employees
INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
GROUP BY FirstName + ' ' + LastName, DATEPART(YEAR, OrderDate)
HAVING SUM(UnitPrice * Quantity) IN
(
SELECT MAX(main.[Total year sale]) FROM TEMP_QUERY AS main
INNER JOIN TEMP_QUERY AS e ON e.Employee = main.Employee
GROUP BY main.Year
)
ORDER BY 1;
However I wonder if there's a simpler way of doing this with or without CTE (probably is) Database scheme. https://docs.yugabyte.com/images/sample-data/northwind/northwind-er-diagram.png
First, your main query is the same as those one used in CTE (except HAVING
and ORDER BY
clauses), so you can just write it as SELECT... FROM temp_query
.
Second, I suggest you not to use the combination of FirstName
and LastName
for aggregation in CTE, since in theory there can be multiple rows for different employees with same values. You have the EmployeeId
you a free to use it instead.
Third, since now the main query does not have any aggregation, you do not need a HAVING
clause, it can be replaced by WHERE
clause.
Fourth, the filter condition (in HAVING
clause of your query) does not need self joining of CTE for getting the maximum of Total year sale
. Just select MAX("Total year sale")
with GROUP BY year
.
Fifth, since I have suggested to use EmployeeId
to perform the aggregation in CTE, join the Employees
table to get the corresponding FirstName
and LastName
values for an employee in results.
Finally the query would look like this
WITH employee_total_sales (
SELECT
e.employeeid,
DATEPART(YEAR, OrderDate) AS year,
SUM(UnitPrice * Quantity) AS total_sale
FROM Employees e
INNER JOIN Orders o ON e.EmployeeID = o.EmployeeID
INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
GROUP BY e.employeeid, DATEPART(YEAR, OrderDate)
)
SELECT
year AS "Year",
FirstName + ' ' + LastName AS "Employee",
total_sale AS "Total year sale"
FROM employee_total_sales ets
JOIN employees e ON e.employeeid = ets.employeeid
WHERE total_sales IN (
SELECT
MAX(total_sale)
FROM employee_total_sales
GROUP BY year
)
ORDER BY year
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.