五种主流数据库:复合查询条件

news/2024/7/9 20:29:17 标签: 数据库, mysql, oracle, sqlserver, postgresql

如果只能使用单个过滤条件,SQL 语句就无法满足复杂的查询需求,例如查找月薪超过10000 的女性员工。为此,SQL 借助于逻辑代数中的运算提供了三个逻辑运算符,可以基于多个运算符构建复杂的过滤条件。

本文比较五种主流数据库对于复合查询条件的实现和差异,包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite。

复合查询条件MySQLOracleSQL ServerPostgreSQLSQLite
AND✔️✔️✔️✔️✔️
OR✔️✔️✔️✔️✔️
NOT✔️✔️✔️✔️✔️
XOR✔️

逻辑与(AND)

对于逻辑与运算符,只有当运算符两边的条件都为真时,才返回数据,否则查询不返回数据。例如,以下语句使用 AND 运算符查找月薪超过 10000 的女性员工:

SELECT emp_name, sex, salary
FROM employee
WHERE sex = '女'
AND salary > 10000;

查询返回的结果如下:

emp_name|sex|salary 
--------|---|--------
孙尚香 ||12000.00

女性员工中只有“孙尚香”的月薪超过了 10000。

AND 运算符的逻辑真值表如下:

x AND yTRUEFALSENULL
TRUETRUEFALSENULL
FALSEFALSEFALSEFALSE
NULLNULLFALSENULL

逻辑或(OR)

对于逻辑或运算符,只要运算符两边的条件有一个为真,就返回数据,否则查询不返回数据。例如,我们可以使用 OR 运算符实现 2.2.1 节中的 IN 运算符示例:

SELECT emp_id, emp_name
FROM employee
WHERE emp_name = '刘备' OR emp_name = '关羽' OR emp_name = '张飞';

该查询同样返回了姓名为“刘备”、“关羽”或者“张飞”的员工。

OR 运算符的逻辑真值表如下:

x OR yTRUEFALSENULL
TRUETRUETRUETRUE
FALSETRUEFALSENULL
NULLTRUENULLNULL

对于逻辑运算符 AND 和 OR,SQL 使用短路运算(Short-Circuit Evaluation)。也就是说,只要左边的表达式能够决定最终的结果就不计算右边的表达式。例如,以下语句不会产生除零错误:

SELECT *
FROM employee
WHERE 1 = 0 AND 1/0 = 1;

SELECT *
FROM employee
WHERE 1 = 1 OR 1/0 = 1;

第一个查询使用了 AND 运算符,由于 1=0 结果为假,查询肯定不会返回任何结果,也就不会计算右边的 1/0。第二个查询使用了 OR 运算符,由于 1=1 结果为真,查询返回全部员工,同样不会计算右边的 1/0。

提示:SQL 语句的短路运算方法可以减少某些情况下的表达式计算,提高运算的效率。

逻辑非(NOT)

逻辑非运算符与其他运算符一起使用时,表示将随后的运算结果取反:

  • NOT >,查找不大于(小于或等于)指定值的数据。也可以使用 NOT=、NOT<等运算符。
  • NOT BETWEEN,查找位于指定范围之外的数据。
  • NOT IN,查找不在指定列表之中的数据。
  • NOT LIKE,查找不匹配某个模式的文本。
  • NOT expr IS NULL,查找 expr 不为空的数据,等价于 expr IS NOT NULL。

例如,以下语句查找奖金小于 2000 或者大于 10 000 的员工:

SELECT emp_name, bonus
FROM employee
WHERE NOT bonus BETWEEN 2000 AND 10000;

查询返回的结果如下:

emp_name|bonus 
--------|-------
蒋琬 |1500.00

虽然有很多员工没有奖金(bonus 字段为空),但是查询并没有返回这些员工的信息,因为未知结果取反之后仍然未知。

NOT 运算的逻辑真值表如下:

xNOT x
TRUEFALSE
FALSETRUE
NULLNULL

逻辑异或(XOR)

除了以上三个标准逻辑运算符之外,MySQL 还实现了一个逻辑异或(XOR )运算符,它在逻辑上等价于以下表达式:

(x AND (NOT y)) OR ((NOT x) AND y)

只要运算符两边的条件有一个为 NULL,结果为 NULL,查询不返回数据;如果有且只有一个条件为真,返回结果;否则,不返回结果。例如:

SELECT 1 XOR 1, 1 XOR 0, 1 XOR NULL;

1 XOR 1|1 XOR 0|1 XOR NULL|
-------+-------+----------+
      0|      1|          |

运算符优先级

我们还需要注意多个运算符之间的优先级问题。一般来说,比较运算符的优先级比逻辑运算符的优先级高,在逻辑运算符中 NOT 比 AND 优先级高,AND 比 OR 的优先级高。通常优先级高的运算符先执行,相同级别的运算符从左至右执行。

我们想要知道人力资源部(dept_id=2)或者财务部(dept_id=3)中有哪些员工有奖金,如果使用以下查询语句:

SELECT emp_name, dept_id, bonus
FROM employee
WHERE dept_id = 2 OR dept_id = 3
AND bonus IS NOT NULL;

返回的结果如下:

emp_name|dept_id|bonus 
--------|-------|-------
诸葛亮 | 2|8000.00
黄忠 | 2| 
魏延 | 2| 
孙尚香 | 3|5000.00

“黄忠”和“魏延”并没有奖金,不是我们期望的结果。那么问题出在哪里了呢?因为 AND 运算符比 OR 运算符的优先级高,以上查询实际返回了人力资源部(dept_id=2)的员工,以及财务部(dept_id=3)中有奖金的员工。

如果想要获得我们期望的结果,可以使用圆括号调整运算符的优先级,例如:

SELECT emp_name, dept_id, bonus
FROM employee
WHERE (dept_id = 2 OR dept_id = 3) AND bonus IS NOT NULL;

查询返回的结果如下:

emp_name|dept_id|bonus 
--------|-------|-------
诸葛亮 | 2|8000.00
孙尚香 | 3|5000.00

http://www.niftyadmin.cn/n/5336501.html

相关文章

React16源码: React中的renderRoot的源码实现

renderRoot 1 &#xff09;概述 renderRoot 是一个非常复杂的方法这个方法里处理很多各种各样的逻辑, 它主要的工作内容是什么&#xff1f;A. 它调用 workLoop 进行循环单元更新 遍历整个 Fiber Tree&#xff0c;把每一个组件或者 dom 节点对应的Fiber 节点拿出来单一的进行更…

pytest.ini 配置

章节目录&#xff1a; 一、概述二、常用配置说明2.1 添加命令行选项2.2 查找测试文件路径2.3 匹配指定的测试文件2.4 匹配指定的测试类2.5 匹配指定的测试函数2.6 自定义的测试标记2.7 变更预期不一致用例的状态2.8 设置运行过程中的命令行日志级别2.9 指定不需要递归搜索的目录…

C 语言->编译和链接实现原理

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;橘橙黄又青-CSDN博客 今天学习&#xff1a;浅学编译和链接内部实现原理 前提&#xff1a;本文是在gcc编译环…

01 MyBatisPlus快速入门

1. MyBatis-Plus快速入门 版本 3.5.31并非另起炉灶 , 而是MyBatis的增强 , 使用之前依然要导入MyBatis的依赖 , 且之前MyBatis的所有功能依然可以使用.局限性是仅限于单表操作, 对于多表仍需要手写 项目结构&#xff1a; 先导入依赖&#xff0c;比之前多了一个mybatis-plus…

Qt —— 编译Qt5版本QFTP库,并实现连接服务、获取列表、上传、下载、删除文件等操作(附源码、附基于Qt5编译好的QFTP库)

示例效果1 示例效果2 介绍 QFTP是Qt4的库,Qt5改用了QNetworkAccessManager来代替。但是Qt5提供的QNetworkAccessManager仅支持FTP的上传和下载,所以只能将QFTP库编译为Qt5的库来进行调用。 QFTP在Github的下载地址:https://github.com/qt/qtftp 客户端源码生成的release结果…

中移(苏州)软件技术有限公司面试问题与解答(2)—— Linux内核内存初始化的完整流程1

接前一篇文章&#xff1a;中移&#xff08;苏州&#xff09;软件技术有限公司面试问题与解答&#xff08;1&#xff09;—— 可信计算国密标准 本文参考以下文章&#xff1a; 启动期间的内存管理之初始化过程概述----Linux内存管理(九) Linux初始化 特此致谢&#xff01; 本…

5分钟教会你如何在生产环境debug代码

前言 有时出现的线上bug在测试环境死活都不能复现&#xff0c;靠review代码猜测bug出现的原因&#xff0c;然后盲改代码直接在线上测试明显不靠谱。这时我们就需要在生产环境中debug代码&#xff0c;快速找到bug的原因&#xff0c;然后将锅丢出去。 生产环境的代码一般都是关闭…

按照一定规则批量修改文件夹内文件的名称

#一个小朋友问我的问题&#xff0c;写好后&#xff0c;就想着分享出来# #目前只想到这一个普通的方法&#xff0c;应该还有更巧妙的方法&#xff0c;读者可以自己思考# 需求&#xff1a;给定文件夹40001&#xff0c;要求将该文件夹内的图片按照40001_00000001,40002_00000002…