1。三值逻辑 1。1。真1。1。1。true 1。2。假1。2。1。false 1。3。不确定1。3。1。unknown2。两种NULL 2。1。未知(unknown)2。1。1。不知道戴墨镜的人眼睛是什么颜色2。1。2。虽然现在不知道,但加上某些条件后就可以知道 2。2。不适用(notapplicable,inapplicable)2。2。1。不知道冰箱的眼睛是什么颜色2。2。2。在语义上更接近于无意义2。2。3。而不是不确定2。2。4。无论怎么努力都无法知道 2。3。Codd提倡在关系数据库中使用四值逻辑2。3。1。现在所有的DBMS都将两种类型的NULL归为了一类并采用了三值逻辑 2。4。数据库里只要存在一个NULL,查询的结果就可能不正确 2。5。最佳方法应该是往表里添加NOTNULL约束来尽力排除NULL3。ISNULL 3。1。谓词 3。2。对NULL使用比较谓词后得到的结果总是unknown3。2。1。以下的式子都会被判为unknown1NULL2NULL3NULL4NULLNULLNULL3。2。2。比较谓词只适用于值3。2。2。1。NULL不是值,所以不能对其使用谓词 3。3。查询结果只会包含WHERE子句里的判断结果为true的行3。3。1。不会包含判断结果为false和unknown的行 3。4。NULL既不是值也不是变量3。4。1。NULL只是一个表示没有值的标记3。4。2。因为NULL不是值,所以不在定义域(domain)中 3。5。ISNULL这样的谓词是由两个单词构成的,所以人们容易把IS当作谓词,而把NULL当作值4。三值逻辑 4。1。AND的情况:falseunknowntrue4。1。1。优先级 4。2。OR的情况:trueunknownfalse4。2。1。优先级5。排中律 5。1。LawofExcludedMiddle 5。2。把命题和它的否命题通过‘或者’连接而成的命题全都是真命题这个命题在二值逻辑中被称为排中律 5。3。在SQL的世界里,排中律是不成立的 5。4。示例5。4。1。查询年龄是20岁或者不是20岁的学生SELECTFROMStudentsWHEREage20ORage20;5。4。2。1约翰年龄是NULL(未知的NULL!SELECTFROMStudentsWHEREageNULLORageNULL;5。4。3。2对NULL使用比较谓词后,结果为unknownSELECTFROMStudentsWHEREunknownORunknown;5。4。4。3。unknownORunknown的结果是unknownSELECTFROMStudentsWHEREunknown;5。4。5。SQL语句的查询结果里只有判断结果为true的行5。4。5。1。添加第3个条件:年龄是20岁,或者不是20岁,或者年龄未知SELECTFROMStudentsWHEREage20ORage20ORageISNULL;6。CASE表达式 6。1。示例6。1。1。col1为1时返回、为NULL时返回的CASE表达式?CASEcol1WHEN1THENWHENNULLTHENEND6。1。2。CASE表达式一定不会返回6。1。2。1。第二个WHEN子句是col1NULL的缩写形式6。1。3。CASEWHENcol11THENWHENcol1ISNULLTHENEND 6。2。CASE表达式的判断方法与WHERE子句一样,只认可真值为true的条件7。NOTEXISTS 7。1。IN改写成EXISTS是等价改写 7。2。NOTIN和NOTEXISTS不是等价的 7。3。示例7。3。1。B班山田的年龄是NULL7。3。2。查询与B班住在东京的学生年龄不同的A班学生的SQL语句?SELECTFROMClassAWHEREageNOTIN(SELECTageFROMClassBWHEREcity’东京’);7。3。2。1。结果是空,查询不到任何数据7。3。3。正确的SQL语句:拉里和伯杰将被查询到SELECTFROMClassAAWHERENOTEXISTS(SELECTFROMClassBBWHEREA。ageB。ageANDB。city’东京’);7。3。4。1执行子查询,获取年龄列表SELECTFROMClassAWHEREageNOTIN(22,23,NULL);7。3。4。1。1在子查询里和NULL进行比较运算SELECTFROMClassAAWHERENOTEXISTS(SELECTFROMClassBBWHEREA。ageNULLANDB。city’东京’);7。3。5。2用NOT和IN等价改写NOTINSELECTFROMClassAWHERENOTageIN(22,23,NULL);7。3。5。1。2对NULL使用后,结果为unknownSELECTFROMClassAAWHERENOTEXISTS(SELECTFROMClassBBWHEREunknownANDB。city’东京’);7。3。6。3用OR等价改写谓词INSELECTFROMClassAWHERENOT((age22)OR(age23)OR(ageNULL));7。3。6。1。3如果AND运算里包含unknown,结果不会是trueSELECTFROMClassAAWHERENOTEXISTS(SELECTFROMClassBBWHEREfalse或unknown);7。3。7。4使用德摩根定律等价改写SELECTFROMClassAWHERENOT(age22)ANDNOT(age23)ANDNOT(ageNULL);7。3。7。1。3如果AND运算里包含unknown,结果不会是trueSELECTFROMClassAAWHERENOTEXISTS(SELECTFROMClassBBWHEREfalse或unknown);7。3。7。2。山田被作为与任何人的年龄都不同的人来处理了7。3。8。5用等价改写NOT和SELECTFROMClassAWHERE(age22)AND(age23)AND(ageNULL);7。3。9。6对NULL使用后,结果为unknownSELECTFROMClassAWHERE(age22)AND(age23)ANDunknown;7。3。10。7如果AND运算里包含unknown,则结果不为trueSELECTFROMClassAWHEREfalse或unknown; 7。4。EXISTS谓词永远不会返回unknown7。4。1。EXISTS只会返回true或者false8。ALL谓词 8。1。多个以AND连接的逻辑表达式的省略写法 8。2。与IN是等价的,所以我们不经常使用ANY 8。3。示例8。3。1。查询比B班住在东京的所有学生年龄都小的A班学生SELECTFROMClassAWHEREageALL(SELECTageFROMClassBWHEREcity’东京’);8。3。1。1。他的年龄比在东京住的所有学生都小8。3。2。1执行子查询获取年龄列表SELECTFROMClassAWHEREageALL(22,23,NULL);2将ALL谓词等价改写为ANDSELECTFROMClassAWHERE(age22)AND(age23)AND(ageNULL);3对NULL使用后,结果变为unknownSELECTFROMClassAWHERE(age22)AND(age23)ANDunknown;4。如果AND运算里包含unknown,则结果不为trueSELECTFROMClassAWHEREfalse或unknown;9。极值函数 9。1。查询比B班住在东京的年龄最小的学生还要小的A班学生SELECTFROMClassAWHEREage(SELECTMIN(age)FROMClassBWHEREcity’东京’);9。1。1。他的年龄比在东京住的年龄最小的学生还要小 9。2。限定谓词和极值函数不是等价的 9。3。极值函数在统计时会把为NULL的数据排除掉 9。4。极值函数在输入为空表(空集)时会返回NULL9。4。1。1极值函数返回NULLSELECTFROMClassAWHEREageNULL;2对NULL使用后结果为unknownSELECTFROMClassAWHEREunknown;10。聚合函数 10。1。COUNT以外的聚合函数当输入为空表时返回NULL 10。2。示例10。2。1。查询比住在东京的学生的平均年龄还要小的A班学生的SQL语句?SELECTFROMClassAWHEREage(SELECTAVG(age)FROMClassBWHEREcity’东京’);10。2。2。没有住在东京的学生时,AVG函数返回NULL10。2。3。外侧的WHERE子句永远是unknown,也就查询不到行