在 Access 2010 中聚合 Child 级别的 Parent 记录

Aggregating Child Records at the Parent Level in Access 2010

上面的 link 将提供 excel sheet 以及来自 parent 和 child table 的一些示例数据查询结果。

好的,这应该很简单,但出于某种原因我无法解决这个问题。差不多,我有一个 parent table linked 到 child table。我想从 child table 中提取一些字段并将其与 parent 字段合并。我想在 Access 中创建排序视图。

parent条记录可以有多个child条记录(1-多关系)。我只想从 child 中提取一条记录并与 parent 合并。 parent table 称为 Tank,child table 称为 Tank_Inspections。您在下面看到的 IF 语句是一个条件语句,有助于确定我应该提取哪个不合规日期。我遇到的问题是不合规日期与检查类型有关。一个 Tank 可以有多种不同的检查类型。他们在下面的查询中将检查不合规日期与少数储罐 (parent) 字段合并。但是,我希望能够添加更多的 child 字段(除了检查不合规日期之外),但如果不将这些字段也添加到 group by 子句中,我就无法做到这一点。如果我这样做,那么我将无法获得正确数量的记录。

如您所见,左连接从 parent table 获取所有记录,这正是我需要的。如果我向查询中添加更多 child table 字段,我还需要将它们添加到 group by 子句中,然后我将获得比 parent 中更多的记录table。本质上,我只需要从 parent table 中获取记录,然后合并 child 字段。我可能会遗漏一些子查询...有什么建议吗?这是我目前所拥有的,并且我得到了正确数量的记录。但是向 select 语句添加更多 child 字段将添加比我需要更多的行...

SELECT parent.tankid, IIf(Min(Nz(child.[tank inspection out of compliance date], #1/1/1901#)) <> #1/1/1901#, Min(child.[tank inspection out of compliance date]), IIf(Min(Nz(child.[tank inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max(child.[tank inspection out of compliance date])>Date(), NULL, Min(child.[tank inspection out of compliance date]))) AS [Tank Inspection Out of Compliance Date] 
FROM 
tank as parent
LEFT JOIN
(
SELECT * FROM tank_inspections WHERE tank_inspections.[actual inspection date] is null
)  AS child ON parent.tankid = child.tankid GROUP BY parent.tankid

我能够修改下面的 Parfait 建议查询来得出这个:

SELECT 
Site.[Manager] AS PM, Site.[DLA Site Code], Tank.[Name] AS [Name], Tank.[Local Name], 
Tank.RPID, Tank.[Fac Num], Tank.[Status], Tank.[Type], Tank.[Capacity], Tank.[Current Prod], IIf(main.[Inspection Out of Compliance Date]<Date() AND NOT IsNull(main.[Inspection Out of Compliance Date]), 'Out of Compliance',
IIf(isnull(main.[Inspection Out of Compliance Date]) OR main.[Inspection Out of Compliance Date]=#1/1/1901#,'Unknown Compliance Status')) AS [Compliance Status], Tank.[EA], Site.Serv, Site.[Name], Tank.Comments, main.[Type], main.[Inspection Out of Compliance Date], main.[Planned Prog Date], main.[Prog Date], main.[Prog Year], main.[Planned Inspection Date], IIf(main.[Inspection Out of Compliance Date]<DateAdd('m',12,Date()) And main.[Prog Date] Is Null,'Action Required') AS [Inspection Planning Action Required], main.[Inspection Comments], tank.TankID, main.inspectionid
FROM 
Site INNER JOIN 
(
(
(
SELECT ti.tankid, ti.inspectionid, ti.[Type], ti.[Inspection Out of Compliance Date], ti.[Planned Prog Date], ti.[Prog Date], ti.[Prog Year], ti.[Planned Inspection Date], ti.[Inspection Comments] FROM Tank_Inspections AS ti)  AS main INNER JOIN Tank ON main.TankID = Tank.TankID) INNER JOIN 
(
SELECT [TankID], dlookup("InspectionID", "Tank_Inspections", "[Tank Inspection Out of Compliance Date] " & IIf(Min(Nz([inspection out of compliance date], #1/1/1901#)) <> #1/1/1901#, "= #" & Min([inspection out of compliance date]) & "#", IIf(Min(Nz([inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max([inspection out of compliance date])>Date(), "IS NULL", IIF(Min(Nz([inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max([inspection out of compliance date])<Date(), "= #" & Min([inspection out of compliance date]) & "#", "IS NULL"))) & " AND TankID = " & TankID & " AND [Actual Inspection Date] is null") AS MinInspectionID FROM Tank_Inspections WHERE [Actual Inspection Date] is null GROUP BY [TankID]
)AS DT ON 
(
main.InspectionID = Cint(DT.MinInspectionID)
) AND (main.TankID = DT.TankID)
) ON Site.SiteID = Tank.SiteID
WHERE IIf(main.[Inspection Out of Compliance Date]<Date() And NOT IsNull(main.[Inspection Out of Compliance Date]),'Out of Compliance',IIf(isnull(main.[Inspection Out of Compliance Date]) OR main.[Inspection Out of Compliance Date]=#1/1/1901#,'Unknown Compliance Status'));

我已经接近这个查询了,但是,我遗漏了一些记录。 parent 记录没有某些 child 记录。例如,有些油罐记录没有任何检查记录,所以没有被拉走。我需要做一个左连接,但似乎无法用这个查询来解决。我尝试的一切似乎都不起作用。建议?

考虑以下使用派生 table 并将单元级父级 (Tank) 连接到聚合子级 (TankInspections) 的查询。您可以将派生的 table 保存为单独的存储查询,只需将整个 select 语句和别名 (DT) 替换为查询名称。我包含了比您检查计算列所需的更多的聚合:

SELECT Tanks.*, main.*, DT.MaxInspectionID, DT.MaxInspectionOrComplianceDate 

FROM
    (TankInspections main
    INNER JOIN Tanks ON Tanks.TankID = main.TankID)
    INNER JOIN    
    (
        SELECT [TankID],    
               Max(InspectionID) As MaxInspectionID,
               Min([Planned Inspection Date]) As MinInspection,
               Max([Planned Inspection Date]) As MaxInspection,    

               Min([Inspection Out of Compliance Date]) As MinCompliance,
               Max([Inspection Out of Compliance Date]) As MaxCompliance,

               Max(IIF(([Planned Inspection Date]) Is Null, 
                       IIF(ISNULL([Inspection Out of Compliance Date]), 
                           NULL, 
                           [Inspection Out of Compliance Date]),
                       [Planned Inspection Date])) As MaxInspectionOrComplianceDate        
        FROM TankInspections
        GROUP BY [TankID]    
    ) As DT

    ON main.TankID = DT.TankID
    AND main.InspectionID = DT.MaxInspectionID;