Reputation: 3813
I can't seem to find out how to get the functionality I want. Here is an example of what my table looks like:
EmpID | ProjectID | hours_worked |
3 1 8
3 1 8
4 2 8
4 2 8
4 3 8
5 4 8
I want to group by EmpID and ProjectID and then sum up the hours worked. I then want to inner join the Employee and Project table rows that are associated with EmpID and ProjectID, however when I do this then I get an error about the aggregate function thing, which I understand from research but I don't think this would have that problem since there will be one row per EmpID and ProjectID.
Real SQL:
SELECT
WorkHours.EmpID,
WorkHours.ProjectID,
Employees.FirstName
FROM WorkHours
INNER JOIN Projects ON WorkHours.ProjectID = Projects.ProjectID
INNER JOIN Employees ON WorkHours.EmpID = Employees.EmpID
GROUP BY WorkHours.ProjectID, WorkHours.EmpID
This gives the error:
Column 'Employees.FirstName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Upvotes: 1
Views: 57
Reputation: 2097
You might want to use OVER (PARTITION BY)
so you won't have to use GROUP BY
:
Select a.EmpID
,W.ProjectID
,W.SUM(hours_worked) OVER (PARTITION BY W.EmpID,W.ProjectID)
,E.FirstName
FROM WorkHours W
INNER JOIN Projects P ON WorkHours.ProjectID = Projects.ProjectID
INNER JOIN Employees E ON WorkHours.EmpID = Employees.EmpID
Upvotes: 3
Reputation: 136134
One way is to use a CTE to first form the data you want, then join onto the other table(s)
WITH AggregatedHoursWorked
AS
(
SELECT EmpID,
ProjectID,
SUM(HoursWorked) AS TotalHours
FROM WorkHours
GROUP BY EmpID, ProjectID
)
SELECT e.FirstName
p.ProjectName,
hw.TotalHours
FROM AggregatedHoursWorked hw
INNER JOIN Employees e
ON hw.EmpID = e.ID
INNER JOIN Projects p
ON hw.ProjectID = p.ID
Upvotes: 1
Reputation: 119017
You can do a basic query to get the grouped hours and use that as a basis for the rest, either in a CTE or as a subquery. For example, as a subquery:
SELECT *
FROM
(SELECT EmpID, ProjectID, SUM(hours_worked) as HoursWorked
FROM WorkHours
GROUP BY EmpID, ProjectID) AS ProjectHours
JOIN Projects
ON Projects.ID = ProjectHours.ProjectID
JOIN Employees
ON Employees.ID = ProjectHours.EmpID
Upvotes: 2
Reputation: 347
If you use an aggregate function, all the columns must be named in the aggregate function and/or in the GROUP BY clause. If you want to join the descriptions (normally unique for a given ID), you have to include the description columns in the GROUP BY clause. This will not affect the result of the query.
Upvotes: 0