首页 > 数据库技术 > 详细

MySQL AND 和 OR 联合使用带来的坑

时间:2019-10-30 20:55:05      阅读:106      评论:0      收藏:0      [点我收藏+]

MySQL 基础篇

三范式

MySQL 军规

MySQL 配置

MySQL 用户管理和权限设置

MySQL 常用函数介绍

MySQL 字段类型介绍

MySQL 多列排序

MySQL 行转列 列转行

MySQL NULL 使用带来的坑

MySQL AND 和 OR 联合使用带来的坑

MySQL 触发器的使用

 

数据准备:

CREATE TABLE products
(
  prod_id    CHAR(10)      NOT NULL ,
  vend_id    CHAR(10)      NOT NULL ,
  prod_name  CHAR(255)     NOT NULL ,
  prod_price DECIMAL(8,2)  NOT NULL ,
  prod_desc  VARCHAR(1000) NULL
);
 
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BR01, BRS01, 8 inch teddy bear, 5.99, 8 inch teddy bear, comes with cap and jacket);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BR02, BRS01, 12 inch teddy bear, 8.99, 12 inch teddy bear, comes with cap and jacket);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BR03, BRS01, 18 inch teddy bear, 11.99, 18 inch teddy bear, comes with cap and jacket);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BNBG01, DLL01, Fish bean bag toy, 3.49, Fish bean bag toy, complete with bean bag worms with which to feed it);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BNBG02, DLL01, Bird bean bag toy, 3.49, Bird bean bag toy, eggs are not included);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(BNBG03, DLL01, Rabbit bean bag toy, 3.49, Rabbit bean bag toy, comes with bean bag carrots);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(RGAN01, DLL01, Raggedy Ann, 4.99, 18 inch Raggedy Ann doll);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(RYL01, FNG01, King doll, 9.49, 12 inch king doll with royal garments and crown);
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES(RYL02, FNG01, Queen doll, 9.49, 12 inch queen doll with royal garments and crown);

查询数据表中的内容:

SELECT * FROM products;

技术分享图片

 

组合 AND 和 OR 带来了一个有趣的问题。为了说明这个问题,来看一个例子。假如需要列出价格为10美元(含)以上且由 BRS01 或 DLL01 制造的所有产品。下面的 SELECT 语句使用 AND 和 OR 操作符的组合建立了一个WHERE 子句:

SELECT prod_name, prod_price
FROM products 
WHERE vend_id = BRS01 
  OR vend_id = DLL01 
  AND prod_price >= 10 ;

技术分享图片

 

请看上面的结果。返回的行中有两行价格小于10美元,显然,返回的行未按预期的进行过滤。为什么会这样呢?

原因在于计算的次序。SQL(像多数语言一样)在处理 OR 操作符前,优先处理 AND 操作符。当 SQL 看到上述 WHERE 子句时,它理解为由供应商 DLL01 制造的任何价格为10美元(含)以上的产品,或者由供应商 BRS01 制造的任何产品,而不管其价格如何。换句话说,由于 AND 在计算次序中优先级更高,操作符被错误地组合了。

此问题的解决方法是使用圆括号明确地分组相应的操作符。请看下面的 SELECT 语句及输出:

SELECT prod_name,prod_price 
FROM products 
WHERE (
    vend_id = BRS01 
    OR vend_id = DLL01
  ) 
  AND prod_price >= 10 ;

这条 SELECT 语句与前一条的唯一差别是,这条语句中,前两个条件用圆括号括了起来。因为圆括号具有较 AND 或 OR 操作符高的计算次序,DBMS 首先过滤圆括号内的 OR 条件。这时,SQL 语句变成了选择由供应商 BRS01 或 DLL01 制造的且价格都在10美元(含)以上的任何产品,这正是我们所希望的。

任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它确实是你想要的东西也是如此。使用圆括号没有什么坏处,它能消除歧义。

 

MySQL AND 和 OR 联合使用带来的坑

原文:https://www.cnblogs.com/yinjw/p/11767431.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!