ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL多条件查询:AND不是拼接条件,还要看边界、NULL和括号

SQL多条件查询:AND不是拼接条件,还要看边界、NULL和括号 原来的 SQL11 题目要求取出 gender 为 male且 GPA 在 3.5 以上、不包括 3.5 的用户返回 device_id、gender、age、university、gpa。拆开就是两个条件同时满足SELECT device_id, gender, age, university, gpa FROM user_profile WHERE gender male AND gpa 3.5;原稿写的是 和带引号的 3.5。在 MySQL 中 可表示逻辑与并不是原题一定运行错误但它是非标准且已弃用的扩展这里改用 AND。GPA 是数值列比较常量直接写数字避免让隐式类型转换掩盖表达意图。MySQL 逻辑运算符说明。1. 为什么不能换成 OR或者把 写成 一个满足性别要求但成绩不够另一个成绩够但不满足性别要求都应该排除。原题也明确排除 3.5不能按日常口语里的“以上”猜测是否包含边界。gendergpa性别匹配GPA严格大于3.5保留male3.4是否否male3.5是否否male3.6是是是female3.6否是否maleNULL是未知否用 OR 会放入不符合全部要求的用户用 会额外放入正好 3.5 的用户。一个很短的条件也值得专门放一行边界数据。2. 自己建立一张能抓错的实验表在自己的练习数据库运行下面独立表。表名存在时换一个名字不需要删除已有数据。为观察 NULL实验允许 gender 为空这比原题的 NOT NULL 约束更宽。CREATE TABLE sql11_and_demo ( id INT NOT NULL PRIMARY KEY, gender VARCHAR(14), gpa DECIMAL(3,1), invited INT NOT NULL ); INSERT INTO sql11_and_demo VALUES (1,male,3.4,0), (2,male,3.5,0), (3,male,3.6,0), (4,female,3.6,1), (5,male,NULL,0), (6,NULL,3.6,0), (7,female,NULL,0), (8,NULL,3.4,0), (9,NULL,NULL,0);SELECT id FROM sql11_and_demo WHERE gender male AND gpa 3.5 ORDER BY id;只返回 3。这里用 DECIMAL 表达一位小数的练习意图原题 gpa 是 FLOAT这不是暗中修改原题字段也没有进行 FLOAT 与 DECIMAL 的性能对比。3. NULL没有筛中不等于每个条件都是假可以先把条件结果取出来而不是只看 WHERE 后还剩谁SELECT id, gender male AS gender_match, gpa 3.5 AS gpa_match, (gender male AND gpa 3.5) AS both_match FROM sql11_and_demo ORDER BY id;其中几行结果idgender_matchgpa_matchboth_match311151NULLNULL70NULL09NULLNULLNULLAND 不是只有真、假两种情况真与未知得到未知假与未知得到假。WHERE 只留下条件为真的行结果为假或未知都不保留。NULL 不应直接当成 0 分只是未提供已知值。官方三值逻辑说明。4. 新加一个 OR可能悄悄改变业务范围现在额外假设仍然只调研 male成绩达标或者已经被邀请都可以。这是扩展实验不是原题要求。下面这句很容易写错SELECT id FROM sql11_and_demo WHERE gender male AND gpa 3.5 OR invited 1 ORDER BY id;AND 的优先级高于 OR它相当于“性别与成绩同时满足或者已邀请”会返回 3 和 4。第 4 行的 female 因为已邀请绕过了性别限制。MySQL 运算符优先级。如果邀请只用于放宽成绩而不能放宽性别括号应该这样写SELECT id FROM sql11_and_demo WHERE gender male AND (gpa 3.5 OR invited 1) ORDER BY id;现在只返回 3。括号不是装饰它决定哪一组条件整体受性别条件约束。原题性别匹配 AND 成绩达标 扩展性别匹配 AND (成绩达标 OR 已邀请)5. 验证不是只放两条能命中的数据本次实际在 SQLite 内存数据库执行正文实验核对命中行、条件的三值结果以及两种括号写法的不同结果。MySQL 的 、优先级和逻辑语义另查官方资料没有实际运行 MySQL也不将 SQLite 的类型系统当作 MySQL DECIMAL/FLOAT 的测试。测试器还把 AND 改成 OR、把 改成 要求能够发现多出来的行并检查空表。这些对照数据各有作用3.5 抓边界female 高分抓逻辑连接NULL 抓未知值已邀请行抓括号范围。写组合条件时我会先用自然语言写清“哪些必须满足哪些可以二选一”再给每个可能误解的地方放一个反例。比只看“SQL执行成功”更能说明查询取对了人。
返回列表