选择一对多关系中的最后记录

时间:2014-05-13 10:44:39

标签: sql ms-access select join indexing

我无法格式化查询以返回一组人,同时从其他可用的表中加入最新记录。

我已经通过SO上的一些示例,但未能找到符合我要求的MS Access 2007特定的一个。

模式如下:

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

我想在查询中返回staff id,first_name,last_name和results(如果可用)。

我已尝试以下操作,但它会返回团队的所有记录,而不仅仅是最新诊断:

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

任何人都可以帮助我们根据表Added中的ct_pm_Diagnostic字段返回最新的诊断结果吗?我的研究表明,我需要在Added上使用MAX函数以及另一个Group By条件,但我很难弄清楚如何使用它们。

1 个答案:

答案 0 :(得分:1)

第一步是从每个工作人员的诊断中获取持续增加的日期:

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

然后,您需要将此查询的结果加回ct_pm_Diagnostic,以便为每位员工的最新记录过滤它:

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;

我认为您可以将其添加回原始查询,如下所示(未经测试):

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

修改

我试图给出最简单的连接方法,但看起来Access不支持它,我看不出任何原因导致以下内容不起作用:

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

如果它仍然无效,您可能最好保存此查询:

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;

LatestDiagnostic类似,您可以在原始查询中将ct_pm_Diagnostic替换为LatestDiagnostic