加入多个布尔值

Posted

技术标签:

【中文标题】加入多个布尔值【英文标题】:Join on multiple booleans 【发布时间】:2009-07-17 22:43:36 【问题描述】:

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

表 1:A1、B1、C1

表 2:A2、B2、C2

如果表 1 中的特定行满足以下条件,我想要表 2 中的行:

如果 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

【问题讨论】:

那应该是下一个相关网站。 domyhomework.com 不,这是真的。我没有作业。抱歉简化了示例。 @onedaywhen:您的评论令人困惑。您似乎的意思是布尔字段应该是 NULLable 并且 Yes/No 字段的 Jet/ACE 实现不是(这是真的)。但是您的第二句话似乎说 Yes/No is Nullable。 Access 数据库引擎的 YESNO 数据类型不是布尔值。 YESNO 不可能是因为,像所有 SQL 数据类型一样,它是 NULLable 即三值逻辑。因此,因为 YESNO 可以有三个值,所以它不是布尔值。另外,我听说 YESNO 数据类型在 NULLability (allenbrowne.com/NoYesNo.html) 方面有问题,所以我建议避免使用它,而不是 example_yesno INTEGER DEFAULT 0 NOT NULL, CHECK (example_yesno IN (0, 1) ) 【参考方案1】:

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

  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 中存在一些问题。一方面,您应该只表达 JOIN 子句中将 vw_fbScheduleFull 表与 fbDivision 表相关联的条件(即外键/主键关系);所有 LowerDivision/UpperDivision/SeniorDivision 的东西都应该在 WHERE 子句中。

其次,您忽略了 AND 和 OR 运算符的运算符优先级 - 您希望将每个 *Division 对括在括号内以避免不良影响。

不知道表的完整架构,我猜这个查询的正确版本应该是这样的:

  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 
;

再看一次,我意识到您的“fbDivision.DivisionName = ?”可能正在将该表中的行数减少到一,并且这两个表之间没有正式的 PK/FK 关系。在这种情况下,您应该放弃 FROM 子句中的 INNER JOIN 命名法,只列出两个表;我已经更新了我的示例。

【讨论】:

+ 1 表示简化的 where 子句。 在我使用“OR NOT”语法创建查询后,它看起来正在工作。我的 IDE(Visual Studio Express)经常重新组织我的 SQL,包括清除括号(如本例所示),或者更经常添加一大堆不需要的括号。我尝试了许多非 JOIN 方法来实现此过滤,但不知何故说服自己需要 JOIN。感谢您的帮助。【参考方案2】:

Steve Broberg 的回答是正确而好的;我只想补充一点,别名可以使查询更容易:

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 
;

【讨论】:

这个答案来自可能不使用 Access,但手动编写 SQL 的人。 在这两个方面都正确。 Access 的 SQL 不包含别名吗?

以上是关于加入多个布尔值的主要内容,如果未能解决你的问题,请参考以下文章

具有多个值的张量的布尔值在 Pytorch 中不明确

多个布尔值上的 Knockout.js“如果绑定”

如何检查任何多个“错误”布尔值是不是为真?

如何测试多个(2个或更多)布尔值是不是为真

python 测试多个布尔值

使用布尔值的 If 语句的语法