Reputation: 345
Ok, so I'm dealing with this messy SQL statement.
What I am trying to do is, count the number of team members on a project (including project manager). When project details are created, members from the Members
table are written to the ProjectIterationMembers
table. A project can consist of 1 or many iterations.
What is happening right now is that when I add a second iteration and assign the same people to the project, I get two sets of data - Project name, 5
....Project name, 10
. How can I make sure that only the max count of members is displayed? Thanks in advance!
SELECT
DISTINCT(Project.ProjectName),
Project.ProjectID,
Project.Status,
Project.CompanyID,
Project.StartDate,
m.MemberID,
m.FirstName + ' ' + m.LastName AS ProjectManager,
(SELECT COUNT(MemberID)
FROM ProjectIterationMember
WHERE ProjectIterationID = i.ProjectIterationID) AS MemberCount
FROM
Project,
Member m,
ProjectIterationMember,
Iterations i
WHERE
m.CompanyRole IN ('Project Manager', 'Admin')
AND Project.CompanyID = '" + co_id + "'
AND m.MemberID = ProjectIterationMember.MemberID
AND i.ProjectIterationID = ProjectIterationMember.ProjectIterationID
AND i.ProjectID = Project.ProjectID ORDER BY Project.StartDate DESC
Upvotes: 1
Views: 151
Reputation: 64645
Some notes:
Distinct( Project.ProjectName )
would do. As far as I know, it would be invalid syntax in any database system. With CountByIteration As
(
Select PIM1.ProjectId, I1.ProjectIterationId
, Count(*) As MemberCount
From Iterations As I1
Join ProjectIterationMembers As PIM1
On PIM1.ProjectIterationId = I1.ProjectIterationId
Group By PIM1.ProjectId, I1.ProjectIterationId
)
, RankedIterations As
(
Select ProjectId, ProjectIterationId
, Row_Number() Over( Partition By I1.ProjectId Order By MemberCount Desc ) As Rnk
From CountByIteration
)
Select P.ProjectName, P.ProjectId, P.Status, P.StartDate
, M.MemberId
, M.FirstName + ' ' + M.LastName As ProjectManager
, IterationMemberCounts.MemberCount
From Project As P
Join RankedIterations As IterationMemberCounts
On IterationMemberCounts.ProjectId = P.ProjectId
And IterationMemberCounts.Rnk = 1
Join ProjectIterationMembers As PIM
On PIM.ProjectIterationId = IterationMemberCounts.ProjectIterationId
Join Members As M
On M.MemberId = PIM.MemberId
And M.CompanyRole In( 'Project Manager', 'Admin' )
Now, it doesn't seem likely that you would want to arbitrarily choose the iteration with the highest member count. Instead, it would make more sense to choose the last iteration. To do that, we need a column that is safe to use to indicate sequence (i.e., not an identity column). If on the Iterations
table there was a column called CreateDate
, then we need only change the way in which the ranking is determined:
, Row_Number() Over( Partition By I1.ProjectId Order By CreateDate Desc ) As Rnk
Upvotes: 2
Reputation: 74909
You need to join the Iterations
table twice, once inside the subquery and also on the outside, and join the inner and outer queries on ProjectID
not ProjectIterationID
.
If iterations cannot have separate project managers per iteration, then you can also refactor the outer Iterations
join to remove the duplicate Project lines. The following will still give you duplicate Project
lines, possibly with different Project Managers, but the MemberCount
will be the same for each.
SELECT
DISTINCT(P.ProjectName),
P.ProjectID,
P.Status,
P.CompanyID,
P.StartDate,
M.MemberID,
M.FirstName + ' ' + M.LastName AS ProjectManager,
( SELECT COUNT(PIM2.MemberID)
FROM ProjectIterationMember PIM2,
Iterations I2
WHERE I2.ProjectID = P.ProjectID
AND PIM2.PIM.ProjectIterationID = I2.ProjectIterationID
) AS MemberCount
FROM
Project P,
Member M,
ProjectIterationMember PIM,
Iterations I
WHERE
M.CompanyRole IN ('Project Manager', 'Admin')
AND P.CompanyID = '" + co_id + "'
AND M.MemberID = PIM.MemberID
AND I.ProjectIterationID = PIM.ProjectIterationID
AND I.ProjectID = P.ProjectID
ORDER BY
P.StartDate DESC
Upvotes: 2