Access 2002 - 几个级别的嵌套内部联接到同一个表(与常规内部联接)?

时间:2011-09-19 22:37:59

标签: sql ms-access

我继承了设计糟糕的Access 2002数据库。我正在尝试解决一些问题,特别是一个查询让我摸不着头脑。它将几个连接嵌套到同一个表中...每个连接都嵌套在前一个连接中,而不是多次连接到同一个表。老实说,我甚至不能确定为什么这个查询有效 - 我从未见过以这种方式创建的连接...任何人都可以评论这些内连接的效果(性能明智吗?)并且我会看到un的性能提升他们是谁?

示例:

--Detals cut
FROM tempMapIDs INNER JOIN 
(BenefitMapRiders AS RxDeduct INNER JOIN 
(BenefitMapRiders AS SubAbuse INNER JOIN 
(BenefitMapRiders AS Infertility INNER JOIN 
(BenefitMapRiders AS Dental INNER JOIN 
(BenefitMapRiders AS Chiro INNER JOIN 
(BenefitMapRiders AS Vision INNER JOIN 
(BenefitMapRiders AS Drug INNER JOIN qryOptionsMap ON Drug.NewRiderOption = qryOptionsMap.Drug) 
ON Vision.NewRiderOption = qryOptionsMap.Vision) 
ON Chiro.NewRiderOption = qryOptionsMap.Chiro) 
ON Dental.NewRiderOption = qryOptionsMap.Dental) 
ON Infertility.NewRiderOption = qryOptionsMap.Infertility) 
ON SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse) 
ON RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct) 

ON (tempMapIDs.NewDate = qryOptionsMap.RenewalDate) 
    AND (tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption) 
    AND (tempMapIDs.RxDeduct = RxDeduct.OldRiderOption) 
    AND (tempMapIDs.SubAbuse = SubAbuse.OldRiderOption) 
    AND (tempMapIDs.Infertility = Infertility.OldRiderOption) 
    AND (tempMapIDs.Chiro = Chiro.OldRiderOption) 
    AND (tempMapIDs.Vision = Vision.OldRiderOption) 
    AND (tempMapIDs.Dental = Dental.OldRiderOption) 
    AND (tempMapIDs.Drug = Drug.OldRiderOption) 
    AND (tempMapIDs.MapID = RxDeduct.MapID) 
    AND (tempMapIDs.MapID = SubAbuse.MapID) 
    AND (tempMapIDs.MapID = Infertility.MapID) 
    AND (tempMapIDs.MapID = Chiro.MapID) 
    AND (tempMapIDs.MapID = Vision.MapID) 
    AND (tempMapIDs.MapID = Dental.MapID) 
    AND (tempMapIDs.MapID = Drug.MapID)
) 

3 个答案:

答案 0 :(得分:3)

当您使用可视化查询设计器创建查询时,这就是Access倾向于编写查询的方式。它不应该比你习惯的等效语法更糟糕。

使用可视化设计器创建一个包含2个或3个连接的新查询,您将看到相同的语法。

答案 1 :(得分:2)

我想我知道你来自哪里。我更喜欢以保持ON子句接近JOIN子句的方式编写相同的连接,以便于阅读和维护,例如:

FROM 
     tempMapIDs 

     INNER JOIN qryOptionsMap 
        ON tempMapIDs.NewDate = qryOptionsMap.RenewalDate
           AND tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption

     INNER JOIN BenefitMapRiders AS RxDeduct 
        ON tempMapIDs.MapID = RxDeduct.MapID
           AND tempMapIDs.RxDeduct = RxDeduct.OldRiderOption
           AND RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct

     INNER JOIN BenefitMapRiders AS SubAbuse 
        ON tempMapIDs.MapID = SubAbuse.MapID
           AND tempMapIDs.SubAbuse = SubAbuse.OldRiderOption
           AND SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse

     INNER JOIN BenefitMapRiders AS Infertility 
        ON tempMapIDs.MapID = Infertility.MapID
           AND tempMapIDs.Infertility = Infertility.OldRiderOption
           AND Infertility.NewRiderOption = qryOptionsMap.Infertility

     INNER JOIN BenefitMapRiders AS Dental
        ON tempMapIDs.MapID = Dental.MapID
           AND tempMapIDs.Dental = Dental.OldRiderOption
           AND Dental.NewRiderOption = qryOptionsMap.Dental

     INNER JOIN BenefitMapRiders AS Chiro 
        ON tempMapIDs.MapID = Chiro.MapID
           AND tempMapIDs.Chiro = Chiro.OldRiderOption 
           AND Chiro.NewRiderOption = qryOptionsMap.Chiro     

     INNER JOIN BenefitMapRiders AS Vision 
        ON tempMapIDs.MapID = Vision.MapID
           AND tempMapIDs.Vision = Vision.OldRiderOption
           AND Vision.NewRiderOption = qryOptionsMap.Vision

     INNER JOIN BenefitMapRiders AS Drug 
        ON tempMapIDs.MapID = Drug.MapID
           AND tempMapIDs.Drug = Drug.OldRiderOption
           AND Drug.NewRiderOption = qryOptionsMap.Drug

请注意,上述联接不是嵌套的,因此优化器可以按照它认为合适的任何顺序自由评估它们。

但是,上面的语法无效(ACE,Jet,无论如何)(遗憾的是,它不支持SQL标准)。相反,它会强制您将每个连接放在括号内。就个人而言,我会将连接保留在上述结构中,并以尽可能不引人注意的方式添加括号,例如:

FROM (((((((
     tempMapIDs 

     INNER JOIN qryOptionsMap 
        ON tempMapIDs.NewDate = qryOptionsMap.RenewalDate
           AND tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption
     )
     INNER JOIN BenefitMapRiders AS RxDeduct 
        ON tempMapIDs.MapID = RxDeduct.MapID
           AND tempMapIDs.RxDeduct = RxDeduct.OldRiderOption
           AND RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct
     )
     INNER JOIN BenefitMapRiders AS SubAbuse 
        ON tempMapIDs.MapID = SubAbuse.MapID
           AND tempMapIDs.SubAbuse = SubAbuse.OldRiderOption
           AND SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse
     )
     INNER JOIN BenefitMapRiders AS Infertility 
        ON tempMapIDs.MapID = Infertility.MapID
           AND tempMapIDs.Infertility = Infertility.OldRiderOption
           AND Infertility.NewRiderOption = qryOptionsMap.Infertility
     )
     INNER JOIN BenefitMapRiders AS Dental
        ON tempMapIDs.MapID = Dental.MapID
           AND tempMapIDs.Dental = Dental.OldRiderOption
           AND Dental.NewRiderOption = qryOptionsMap.Dental
     )
     INNER JOIN BenefitMapRiders AS Chiro 
        ON tempMapIDs.MapID = Chiro.MapID
           AND tempMapIDs.Chiro = Chiro.OldRiderOption 
           AND Chiro.NewRiderOption = qryOptionsMap.Chiro     
     )
     INNER JOIN BenefitMapRiders AS Vision 
        ON tempMapIDs.MapID = Vision.MapID
           AND tempMapIDs.Vision = Vision.OldRiderOption
           AND Vision.NewRiderOption = qryOptionsMap.Vision
     )
     INNER JOIN BenefitMapRiders AS Drug 
        ON tempMapIDs.MapID = Drug.MapID
           AND tempMapIDs.Drug = Drug.OldRiderOption
           AND Drug.NewRiderOption = qryOptionsMap.Drug

注意上面只给出了嵌套连接的外观,但实际上优化器仍然可以按任意顺序自由评估它们(这会导致功能丧失 - 无法指定显式订单 - 但这是给你的访问!)

答案 2 :(得分:0)

如果查询效果不佳,则应确保将连接中使用的字段编入索引。