Question

I'm having trouble formatting a query to return a team of people whilst joining their latest record from another table where available.

I've been through a number of examples on SO but have been unable to find one specific to MS Access 2007 that suits my requirements.

The schemas are as follows:

dbo_ds_staff

id
first_name
last_name

dbo_ds_team_staff_member

id
team_id
staff_id
start_date
end_date

dbo_ds_team_leader

id
team_id
staff_id
start_date
end_date

ct_pm_Diagnostic

id
staff_id
outcome_id
Added

ct_pm_Outcome

id
outcome

I'm wanting to return in the query the staff id, first_name, last_name and outcome (if available).

I've tried the following but it returns all the records for the team not just the latest diagnostic:

SELECT s.id, s.first_name, s.last_name, o.Outcome 
    FROM ((SELECT s.id, s.first_name, s.last_name 
        FROM ((dbo_ds_staff AS s 
            INNER JOIN dbo_ds_team_staff_member AS tsm ON s.id=tsm.staff_id) 
            INNER JOIN dbo_ds_team_leader AS tl ON tsm.team_id=tl.team_id) 
            WHERE tl.staff_id = 26928 And tsm.start_date < Now() And (tsm.end_date >= Now() Or tsm.end_date Is Null) And tl.start_date < Now() And (tl.end_date >= Now() Or tl.end_date Is Null) 
            GROUP BY s.id, s.first_name, s.last_name) as s 
    LEFT JOIN ct_pm_Diagnostic AS d ON s.id=d.StaffId) 
    LEFT JOIN ct_pm_Outcome AS o ON d.OutcomeId = o.OutcomeId 
    ORDER BY s.first_name, s.last_name

Could anyone help with how to only return the latest diagnostic result based on the Added field in from the table ct_pm_Diagnostic? My research indicates that I need to be using the MAX function on Added along with another Group By condition but I struggling to figure out how to utilse them.

Was it helpful?

Solution

The first step is to get the lasted added date from diagnistic per staff member:

SELECT  d.StaffID, MAX(Added) AS MaxAdded
FROM    ct_pm_Diagnostic
GROUP BY d.StaffID;

You would then need to join the results of this query back to ct_pm_Diagnostic to filter it just for the latest record for each staff member:

SELECT  d.*
FROM    ct_pm_Diagnostic AS d
        INNER JOIN
        (   SELECT  d.StaffID, MAX(Added) AS Added
            FROM    ct_pm_Diagnostic
            GROUP BY d.StaffID
        ) AS MaxD
            ON MaxD.StaffID = d.StaffID
            AND MaxD.Added = d.Added;

I think you can then add this back to your original query as follows (Untested):

SELECT s.id, s.first_name, s.last_name, o.Outcome 
    FROM ((SELECT s.id, s.first_name, s.last_name 
        FROM ((dbo_ds_staff AS s 
            INNER JOIN dbo_ds_team_staff_member AS tsm ON s.id=tsm.staff_id) 
            INNER JOIN dbo_ds_team_leader AS tl ON tsm.team_id=tl.team_id) 
            WHERE tl.staff_id = 26928 And tsm.start_date < Now() And (tsm.end_date >= Now() Or tsm.end_date Is Null) And tl.start_date < Now() And (tl.end_date >= Now() Or tl.end_date Is Null) 
            GROUP BY s.id, s.first_name, s.last_name) as s 
    LEFT JOIN (ct_pm_Diagnostic AS d 
        INNER JOIN (SELECT d.StaffID, MAX(Added) AS Added
                    FROM ct_pm_Diagnostic
                    GROUP BY d.StaffID) AS MaxD 
            ON MaxD.StaffID = d.StaffID AND MaxD.Added = d.Added)
        ON s.id=d.StaffId) 
    LEFT JOIN ct_pm_Outcome AS o ON d.OutcomeId = o.OutcomeId 
    ORDER BY s.first_name, s.last_name

EDIT

I tried to give the least verbose join method possible, but it looks like Access doesn't support it, I can't see any reason why the below wouldn't work:

SELECT s.id, s.first_name, s.last_name, o.Outcome 
    FROM ((SELECT s.id, s.first_name, s.last_name 
        FROM ((dbo_ds_staff AS s 
            INNER JOIN dbo_ds_team_staff_member AS tsm ON s.id=tsm.staff_id) 
            INNER JOIN dbo_ds_team_leader AS tl ON tsm.team_id=tl.team_id) 
            WHERE tl.staff_id = 26928 And tsm.start_date < Now() And (tsm.end_date >= Now() Or tsm.end_date Is Null) And tl.start_date < Now() And (tl.end_date >= Now() Or tl.end_date Is Null) 
            GROUP BY s.id, s.first_name, s.last_name) as s 
    LEFT JOIN (SELECT d.*
                FROM ct_pm_Diagnostic AS d
                    INNER JOIN
                    (   SELECT  d.StaffID, MAX(Added) AS Added
                        FROM    ct_pm_Diagnostic
                        GROUP BY d.StaffID
                    ) AS MaxD
                        ON MaxD.StaffID = d.StaffID
                        AND MaxD.Added = d.Added) AS d
        ON s.id=d.StaffId) 
    LEFT JOIN ct_pm_Outcome AS o ON d.OutcomeId = o.OutcomeId 
    ORDER BY s.first_name, s.last_name

If it still doesn't work you may be best off saving this query:

SELECT  d.*
FROM    ct_pm_Diagnostic AS d
        INNER JOIN
        (   SELECT  d.StaffID, MAX(Added) AS Added
            FROM    ct_pm_Diagnostic
            GROUP BY d.StaffID
        ) AS MaxD
            ON MaxD.StaffID = d.StaffID
            AND MaxD.Added = d.Added;

As something like LatestDiagnostic, then you can just replace ct_pm_Diagnostic with LatestDiagnostic in your original query.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top