代码之家  ›  专栏  ›  技术社区  ›  Degan

在多个布尔上连接

  •  0
  • Degan  · 技术社区  · 17 年前

    我有两个表,每个表有三个布尔(ms access“是/否”)列。

    表1:A1、B1、C1

    我希望表2中的行给定表1中满足以下条件的特定行:

    如果A1为真,则只有A2为真的行,如果A1为假,则A2为真或假的行。 如果B1为真,则仅B2为真的行,如果B1为假,则B2为真或假的行。 如果C1为真,则仅限C2为真的行,如果C1为假,则为C2为真或假的行。

    例一

             A, B, C    
    Table 1: 0, 1, 0  (selected row)
    
    Table 2: 1, 0, 0
             0, 1, 0  (in return set)
             1, 1, 0  (in return set)
             0, 0, 1
             1, 0, 1
             0, 1, 1  (in return set)
             1, 1, 1  (in return set)
    

             A, B, C    
    Table 1: 0, 0, 1  (selected row)
    
    Table 2: 1, 0, 0
             0, 1, 0  
             1, 1, 0 
             0, 0, 1  (in return set)
             1, 0, 1  (in return set)
             0, 1, 1  (in return set)
             1, 1, 1  (in return set)
    

    我如何才能最好地完成这一点?

    例如,这不起作用:

    SELECT        vw_fbScheduleFull.LocationName
                , vw_fbScheduleFull.FieldName
                , vw_fbScheduleFull.Description
                , vw_fbScheduleFull.StartTime
                , vw_fbScheduleFull.EndTime
                , vw_fbScheduleFull.LowerDivision
                , vw_fbScheduleFull.UpperDivision
                , vw_fbScheduleFull.SeniorDivision
    FROM (vw_fbSchedule
          Full INNER JOIN fbDivision
             ON vw_fbScheduleFull.LowerDivision = fbDivision.LowerDivision
             AND fbDivision.LowerDivision = 1
             OR vw_fbScheduleFull.UpperDivision = fbDivision.UpperDivision
             AND fbDivision.UpperDivision = 1
             OR vw_fbScheduleFull.SeniorDivision = fbDivision.SeniorDivision   
             AND fbDivision.SeniorDivision = 1)
    WHERE (vw_fbScheduleFull.PracticeDate = ?)
        AND (vw_fbScheduleFull.Locked IS NULL)
        AND (fbDivision.DivisionName = ?)
    ORDER BY vw_fbScheduleFull.LocationName
           , vw_fbScheduleFull.FieldName
           , vw_fbScheduleFull.StartTime
    
    2 回复  |  直到 8 年前
        1
  •  3
  •   Steve Broberg    17 年前

    这不是一个真正的SQL问题,只是一个布尔表达式问题。我假设这些表中有另一列,允许您将t1到t2中的行连接起来,但是按照您的示例(t1中只有一行),您可以这样做:

      SELECT t2.A2
           , t2.B2
           , t3.C2
        FROM t1
           , t2
       WHERE (t2.A2 OR NOT T1.A1)
         AND (t2.B2 OR NOT T1.B1)
         AND (t2.C2 OR NOT T1.C1)
    ;
    

    我现在看到了您在上面发布的非抽象答案。基于此,SQL中存在一些问题。首先,您应该只在连接子句中表示将vw_fbScheduleFull表与fbDivision表关联的条件(即外键/主键关系);所有低分/高分/高分的内容都应该在WHERE子句中。

    其次,您忽略了AND和OR运算符的运算符优先级-您希望将每个*除法对都包含在paren中,以避免不必要的影响。

    由于不知道表的完整模式,我猜想此查询的正确版本如下所示:

      SELECT vw_fbScheduleFull.LocationName
           , vw_fbScheduleFull.FieldName
           , vw_fbScheduleFull.Description
           , vw_fbScheduleFull.StartTime
           , vw_fbScheduleFull.EndTime
           , vw_fbScheduleFull.LowerDivision
           , vw_fbScheduleFull.UpperDivision
           , vw_fbScheduleFull.SeniorDivision
        FROM vw_fbScheduleFull 
           , fbDivision
       WHERE vw_fbScheduleFull.PracticeDate = ?
         AND vw_fbScheduleFull.Locked IS NULL 
         AND fbDivision.DivisionName = ?
         AND (vw_fbScheduleFull.LowerDivision = 1 OR fbDivision.LowerDivision <> 1)
         AND (vw_fbScheduleFull.UpperDivision = 1 OR fbDivision.UpperDivision <> 1)
         AND (vw_fbScheduleFull.SeniorDivision = 1 OR fbDivision.SeniorDivision <> 1)
    ORDER BY vw_fbScheduleFull.LocationName
           , vw_fbScheduleFull.FieldName
           , vw_fbScheduleFull.StartTime 
    ;
    

        2
  •  0
  •   Carl Manaster    17 年前

    史蒂夫·布罗伯格的回答是正确的和好的;我只想补充一点,别名可以让查询变得更容易:

    SELECT f.LocationName
           , f.FieldName
           , f.Description
           , f.StartTime
           , f.EndTime
           , f.LowerDivision
           , f.UpperDivision
           , f.SeniorDivision
        FROM vw_fbScheduleFull f
           , fbDivision        d
       WHERE f.PracticeDate = ?
         AND f.Locked IS NULL 
         AND d.DivisionName = ?
         AND (f.LowerDivision = 1 OR d.LowerDivision <> 1)
         AND (f.UpperDivision = 1 OR d.UpperDivision <> 1)
         AND (f.SeniorDivision = 1 OR d.SeniorDivision <> 1)
    ORDER BY f.LocationName
           , f.FieldName
           , f.StartTime 
    ;
    
    推荐文章