I have 3 tables on my db, Projects, ProljectAllocationLog and Users
Project consists of Projectid(PK), ProjectName
ProjectAllocationLog consists of ProjectAllocationID(PK), Projectid, Users consists of UserID (PK), Fullname
ProjectID ProjectName
1234 ProjectOne
2346 ProjectTwo
7892 ProjectThree
ProjectAllocationLogID ProjectID UserID
1 1234 1
2 2346 3
3 2346 1
4 1234 2
5 7892 2
6 1234 3
7 7892 1
8 7892 2
UserID UserName
1 Debbie Coates
2 Fred Bloggs
3 Jack Smith
I want to be able to view a list of showing the most current User for each project
eg
ProjectID UserName
1234 Jack Smith
2346 DebbieCoates
7892 Fred Bloggs
SELECT Max(ProjectAllocationLog.projectAllocationLogID) AS MaxOfprojectAllocationLogID, ProjectAllocationLog.ProjectID
INTO #TEMP
FROM ProjectAllocationLog
GROUP BY ProjectAllocationLog.ProjectID;
SELECT [#TEMP].ProjectID, ProjectAllocationLog.UserID, Users.UserName
INTO #TEMP2
FROM Users INNER JOIN ([#TEMP] INNER JOIN ProjectAllocationLog ON [#TEMP].MaxOfprojectAllocationLogID = ProjectAllocationLog.projectAllocationLogID) ON Users.Userid = ProjectAllocationLog.UserID;
Select * from #Temp2
I have created this, which shows me the results I want, but think it is really clumsy, Is there a way of doing this so that I dont need to create the Temp tables?SELECT P.ProjectID
, PA.UserID
, U.UserName
FROM Projects as P
INNER
JOIN ProjectAllocationLog as PA
ON PA.ProjectID = P.ProjectID
AND PA.ProjectAllocationLogID =
( SELECT MAX(projectAllocationLogID)
FROM ProjectAllocationLog
WHERE ProjectID = P.ProjectID )
INNER
JOIN Users as U
ON U.Userid = PA.UserID
Showing posts with label projectid. Show all posts
Showing posts with label projectid. Show all posts
Wednesday, March 21, 2012
Friday, March 9, 2012
JOIN, GROUP BY, or HAVING question
Consider the following two tables:
ProjectHours
hoursID {primary key}
employeeID {foreign key}
ProjectDate
ProjectID
ProjectHours
DataComplete
DataCompleteID {primary key}
employeeID {foreign key}
CompleteDate
The first table should be self-explanatory. The second table is there to let me know that a particular employee has entered all of the data for a given date. This tells me that I can include this data in reports and charts.
Here's where I'm having troubles ...
I want to calculate the average hours worked by an employee on a project during a given time period. For example, what is the average number of hours John worked on Project X during the past week? The tricky part is that the employee/date combo must also be found in the
DataComplete table.
Problem: The following SQL statement averages ALL of the data even for dates NOT included in the DataComplete table:
SELECT
AVG(h.ProjectHours) AS avg_hours
FROM
ProjectHours h
JOIN
DataComplete d
ON
h.employeeID = d.employeeID
WHERE
d.employeeID = 123
AND d.CompleteDate >= '7/26/2003'
AND d.CompleteDate <= '8/1/2003'
AND h.ProjectID = 8
How do I get aggregate info only for dates found in the DataComplete table?I see you have a primary key on your ProjectHours table, but what is the NATURAL key?
Do employeeID, ProjectDate, and ProjectID constitute a unique records? If so, try this:
SELECT
AVG(h.ProjectHours) AS avg_hours
FROM
ProjectHours h
INNER JOIN DataComplete d
ON h.employeeID = d.employeeID
AND h.ProjectDate = d.CompleteDate
WHERE
d.employeeID = 123
AND d.CompleteDate >= '7/26/2003'
AND d.CompleteDate <= '8/1/2003'
AND h.ProjectID = 8
If this is not the case, I suspect you will need to modify (normalize) your table design to do what you want to do.
blindman
ProjectHours
hoursID {primary key}
employeeID {foreign key}
ProjectDate
ProjectID
ProjectHours
DataComplete
DataCompleteID {primary key}
employeeID {foreign key}
CompleteDate
The first table should be self-explanatory. The second table is there to let me know that a particular employee has entered all of the data for a given date. This tells me that I can include this data in reports and charts.
Here's where I'm having troubles ...
I want to calculate the average hours worked by an employee on a project during a given time period. For example, what is the average number of hours John worked on Project X during the past week? The tricky part is that the employee/date combo must also be found in the
DataComplete table.
Problem: The following SQL statement averages ALL of the data even for dates NOT included in the DataComplete table:
SELECT
AVG(h.ProjectHours) AS avg_hours
FROM
ProjectHours h
JOIN
DataComplete d
ON
h.employeeID = d.employeeID
WHERE
d.employeeID = 123
AND d.CompleteDate >= '7/26/2003'
AND d.CompleteDate <= '8/1/2003'
AND h.ProjectID = 8
How do I get aggregate info only for dates found in the DataComplete table?I see you have a primary key on your ProjectHours table, but what is the NATURAL key?
Do employeeID, ProjectDate, and ProjectID constitute a unique records? If so, try this:
SELECT
AVG(h.ProjectHours) AS avg_hours
FROM
ProjectHours h
INNER JOIN DataComplete d
ON h.employeeID = d.employeeID
AND h.ProjectDate = d.CompleteDate
WHERE
d.employeeID = 123
AND d.CompleteDate >= '7/26/2003'
AND d.CompleteDate <= '8/1/2003'
AND h.ProjectID = 8
If this is not the case, I suspect you will need to modify (normalize) your table design to do what you want to do.
blindman
Labels:
consider,
database,
employeeid,
following,
foreign,
group,
hoursid,
key,
microsoft,
mysql,
oracle,
primary,
projectdate,
projecthoursdatacomplete,
projectid,
server,
sql,
tablesprojecthours
Subscribe to:
Posts (Atom)