I think you were on the right track in both your attempts.
Here's a correlated subquery way:
SELECT projectid, userID, AllocationLogID
FROM projectAllocationLog P1
WHERE AllocationLogID = (SELECT MAX(AllocationLogID ) FROM projectAllocationLog P2 WHERE P2.ProjectID = P1.ProjectID)
Note the table in the FROM clause is the projectAllocationLog and not the Projects table as in your first attempt. If you were to need the projectName or other columns from the Projects table, just JOIN the projectAllocationLog to it on the projectID.
Another way using the IN clause:
SELECT projectid, userID, AllocationLogID
FROM projectAllocationLog
WHERE AllocationLogID in (SELECT MAX(AllocationLogID ) FROM projectAllocationLog GROUP BY projectID)
It's not clear to me which way is more efficient. Looking at the generated query plan for both I was a bit surprised to find the first query looked like it was a bit better. I'm not sure that would hold up if there were a large number of rows in the table, though. YMMV.
As an aside, I think you would be better served having a column which specifically defined what the "maximum" (by which I assume you really mean the "latest") entry for a given project is. I'm guessing your AllocationLogID is an identity column and you are using the fact that these values are increasing to be a surrogate for the time ordering of log entries. It works in this particular case, so there is no arguing with success, but having something like a EntryDate datetime value makes it clear that you are in fact searching for the latest entry rather than the largest ID, which may not be the same thing in every problem domain...
Jeff Mason
[email protected]