我有两个表,每个表有三个布尔(ms-access“是/否”)列。
表1:A1,B1,C1
表2:A2,B2,C2
我希望表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
答案 0 :(得分:3)
这不是你问的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对包含在parens中以避免不良影响。
不知道表的完整模式,我猜这个查询的正确版本看起来像这样:
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 =?”可能是将该表中的行数减少为1,并且这两个表之间没有正式的PK / FK关系。在这种情况下,您应该省略FROM子句中的INNER JOIN命名法,并列出两个表;我已经更新了我的例子。
答案 1 :(得分:0)
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
;