25.2 MySQL 运算符

2023-10-24_00005

1. 伪表

在MySQL中, DUAL是一个特殊的单行, 单列的虚拟表, 主要用于在SELECT语句中计算表达式或执行函数, 而不需要从实际的数据表中检索数据.
使用DUAL的原因主要有以下几点:

* 1. 简化计算: 通过在SELECT语句中使用DUAL, 可以方便地计算表达式或执行函数, 而无需创建临时表或执行子查询.
* 2. 统一语法: 在某些情况下, 使用DUAL可以使SQL语句保持统一的语法结构, 简化代码逻辑.
* 3. 性能优化: 由于DUAL是虚拟表, 不会占用实际的磁盘空间, 也不会对性能产生负面影响.

2. 算术运算

算术运算符主要用于数学运算, 可以连接运算符前后的两个数值或表达式, 对数值或表达式进行运算.
运算符名称作用示例
+加法运算符计算两个值或表达式的和SELECT A + B
-减法运算符计算两个值或表达式的差SELECT A - B
*乘法运算符计算两个值或表达式的乘积SELECT A * B
/ 或 DIV除法运算符计算两个值或表达式的商SELECT A / B 或者 SELECT A DIV B
% 或 MOD求模(求余)运算符计算两个值或表达式的余数SELECT A % B 或者 SELECT A MOD B
注意事项:
* 1. MySQL中对于非整型的表达式进行隐式转换时, 会尝试将其转换为数值类型.
     如果转换成功, 则使用转换后的数值进行计算; 如果转换失败, MySQL通常会将该表达式按0计算.
     这种行为是为了确保查询的执行不会因为非数值类型的表达式而中断.

     隐式转换可能会导致一些意想不到的结果, 尤其是当转换失败时.
     因此, 在编写MySQL查询时, 最好确保使用的数据类型是匹配的, 以避免潜在的问题.
 
* 2. 以下类型的字符串可以被转为数值:
     整数字符串: 由数字字符(0-9)组成的字符串, 可以表示一个整数. 例如. "123"可以被转为数值123.
     浮点数字符串: 由数字字符和小数点组成的字符串, 可以表示一个浮点数(小数). 例如, "3.14"可以被转为数值3.14.
     科学计数法字符串: 使用科学计数法表示的数值字符串, 例如, "1.23E4"可以被转为数值12300.0.
     
     字符串中的空格和其他非数字字符可能会导致转换失败.
     此外, 某些特殊情况下, 如超出数值类型范围或格式不符合要求, 转换也可能失败.


* 3. 在数学运算中, 0不能用作除数; 在MySQL中, 一个数除以0为NULL.
* 4. 与浮点数进程计算得到的结果是浮点数, 除法运算的结果是浮点数(不管是否能除尽, 结果都为一个浮点数).

2.1 加减法运算

-- 加法
mysql> SELECT 1 + 2;
+-------+
| 1 + 2 |
+-------+
|     3 |
+-------+
1 row in set (0.00 sec)
-- 使用伪表统一语法
mysql> SELECT 1 + 2 FROM DUAL;
+-------+
| 1 + 2 |
+-------+
|     3 |
+-------+
1 row in set (0.00 sec)
-- 纯数字字符串(包括整数和浮点数), 可以转换为整型.
mysql> SELECT 1 + '1' FROM DUAL;
+---------+
| 1 + '1' |
+---------+
|       2 |
+---------+
1 row in set (0.00 sec)
-- 不同数据类型相加, 字符串无法转换为数字按0计算.
mysql> SELECT 1 + 'A' FROM DUAL;
+---------+-----------+
| 1 + 'A' | 'A' + 'A' |
+---------+-----------+
|       1 |         0 |
+---------+-----------+
1 row in set, 1 warning (0.00 sec)
-- 减法运算
mysql> SELECT 1 - 1 FROM DUAL;
+-------+
| 1 - 1 |
+-------+
|     0 |
+-------+
1 row in set (0.00 sec)

-- 纯数字字符串(包括整数和浮点数), 可以转换为整型.
mysql> SELECT 1 - '1' FROM DUAL;
+---------+
| 1 - '1' |
+---------+
|       0 |
+---------+
1 row in set (0.00 sec)

2.2 乘除法运算

mysql> SELECT 100 * 1, 100 * 1.0, 100 / 1.0, 100 / 2, 100 + 2 * 5 / 2, 100 / 3, 100 FROM DUAL;
+---------+-----------+-----------+---------+-----------------+---------+-----+
| 100 * 1 | 100 * 1.0 | 100 / 1.0 | 100 / 2 | 100 + 2 * 5 / 2 | 100 / 3 | 100 |
+---------+-----------+-----------+---------+-----------------+---------+-----+
|     100 |     100.0 |  100.0000 | 50.0000 |        105.0000 | 33.3333 | 100 |
+---------+-----------+-----------+---------+-----------------+---------+-----+
1 row in set (0.00 sec)

2.3 求模运算

mysql> SELECT 10 % 2, 10 % 3 FROM DUAL;
+--------+--------+
| 10 % 2 | 10 % 3 |
+--------+--------+
|     0  |      1 |
+--------+--------+
1 row in set (0.00 sec)
-- 筛选出员工表中employee_id是偶数的员工名字:
mysql> SELECT first_name FROM employees WHERE employee_id % 2 = 0;
+-------------+
| first_name  |
+-------------+
| Steven      |
| ...         | -- 省略
| Hermann     |
| William     |
+-------------+
54 rows in set (0.03 sec)

3. 比较运算符

比较运算符: 用来对表达式左边的操作数和右边的操作数进行比较, 比较的结果为真则返回1, 比较的结果为假则返回0, 其他情况则返回NULL.
比较运算符经常被用来作为SELECT查询语句的条件来使用, 返回符合条件的结果记录.
运算符名称作用例示
=等于判断两个值, 字符串或表达式是否相等SELECT C FROM TABLE WHERE A= B
<=>安全等于安全地判断两个值, 字符串或表达式是否相等SELECT C FROM TABLE WHERE A<=>B
!= 或 <>不等于判断两个值, 字符串或表达式是否不相等SELECT C FROM TABLE WHERE A!= B
<小于判断前面的值, 字符串或表达式是否小于后面的值, 字符串或表达式SELECT C FROM TABLE WHERE A<B
<=小于等于判断前面的值, 字符串或表达式是否小于等于后面的值, 字符串或表达式SELECT C FROM TABLE WHERE A<= B
>大于判断前面的值, 字符串或表达式是否大于后面的值, 字符串或表达式SELECT C FROM TABLE WHERE A>B
>=大于等于判断前面的值, 字符串或表达式是否大于等于后面的值l, 字符串或表达式SELECT C FROM TABLE WHERE A>= B
注意事项: 
* SQL中赋值符号使用( := ).
* 整型与字符比较时, 会将字符串进行隐式转换, 转换失败则按0计算.
* 字符串之间按ASCII编码的数字进行比较.

3.1 等号

mysql> SELECT 1 = 1, 1 = '1', 0 = 'a', 'a' = 'a', (5 + 3) = (2 + 6), '' = NULL , NULL = NULL;
+-------+---------+---------+-----------+-------------------+-----------+-------------+
| 1 = 1 | 1 = '1' | 0 = 'a' | 'a' = 'a' | (5 + 3) = (2 + 6) | '' = NULL | NULL = NULL |
+-------+---------+---------+-----------+-------------------+-----------+-------------+
|     1 |       1 |       1 |         1 |                 1 |      NULL |        NULL |
+-------+---------+---------+-----------+-------------------+-----------+-------------+
1 row in set, 1 warning (0.00 sec)
-- 查询员工表工资为10000的员工名字:
mysql> SELECT first_name FROM employees WHERE salary = 10000;
+------------+
| first_name |
+------------+
| Peter      |
| Janette    |
| Harrison   |
| Hermann    |
+------------+
4 rows in set (0.00 sec)

3.2 安全等于

安全等于运算符( <=> )可以用来对NULL进行判断.
其中一个操作数为NULL时, 其返回值为0, 而不为NULL.
在两个操作数均为NULL时, 其返回值为1, 而不为NULL;
mysql> SELECT 1 <=> '1', 1 <=> 0, 'a' <=> 'a', (5 + 3) <=> (2 + 6), '' <=> NULL, NULL <=> NULL FROM DUAL;
+-----------+---------+-------------+---------------------+-------------+---------------+
| 1 <=> '1' | 1 <=> 0 | 'a' <=> 'a' | (5 + 3) <=> (2 + 6) | '' <=> NULL | NULL <=> NULL |
+-----------+---------+-------------+---------------------+-------------+---------------+
|         1 |       0 |           1 |                   1 |           0 |             1 |
+-----------+---------+-------------+---------------------+-------------+---------------+
1 row in set (0.00 sec)
-- 查询员工表中佣金百分比为NULL的员工名字和佣金百分比:
mysql> SELECT first_name, commission_pct FROM employees WHERE commission_pct <=> NULL;
+-------------+----------------+
| first_name  | commission_pct |
+-------------+----------------+
| Steven      |           NULL |
| Neena       |           NULL |
| ...         |           ...  | -- 省略
| Hermann     |           NULL |
| Shelley     |           NULL |
| William     |           NULL |
+-------------+----------------+
72 rows in set (0.00 sec)

3.3 不等于

不等于运算符用于判断两边的数字, 字符串或者表达式的值是否不相等, 如果不相等则返回1, 相等则返回0.
mysql> SELECT 1 <> 1, 1 != 2, 'a' != 'b', (3+4) <> (2+6), 'a' != NULL, NULL <> NULL;
+--------+--------+------------+----------------+-------------+--------------+
| 1 <> 1 | 1 != 2 | 'a' != 'b' | (3+4) <> (2+6) | 'a' != NULL | NULL <> NULL |
+--------+--------+------------+----------------+-------------+--------------+
|      0 |      1 |          1 |              1 |        NULL |         NULL |
+--------+--------+------------+----------------+-------------+--------------+
1 row in set (0.00 sec)

3.4 大于小于

-- 查询员工表中工资在6000到8000之间的员工名字, 和薪资, 不包括6000和8000.
mysql> SELECT first_name, salary FROM employees WHERE salary > 6000 AND salary < 8000;
+-------------+---------+
| first_name  | salary  |
+-------------+---------+
| Ismael      | 7700.00 |
| Jose Manuel | 7800.00 |
| ...         | ...     |
| Kimberely   | 7000.00 |
| Charles     | 6200.00 |
| Susan       | 6500.00 |
+-------------+---------+
19 rows in set (0.00 sec)

4. 比较运算关键字

运算符名称描述示例
IS NULL为空运算判断值, 字符串或表达式是否为空SELECT B FROM TABLE WHERE A IS NULL
IS NOT NULL不为空运算判断值, 字符串或表达式是否不为空SELECT B FROM TABLE WHERE A IS NOT NULL
LEAST最小值运算在多个值中返回最小值SELECT D FROM TABLE WHERE C = LEAST(A,B)
GREATEST最大值运算在多个值中返回最大值SELECT D FROM TABLE WHERE C = GREATEST(A,B)
BETWEEN ... AND ...两值之间的运算判断一个值是否在两个值之间SELECT D FROM TABLE WHERE C BETWEEN A AND B
ISNULL为空运算判断一个值, 字符串或表达式是否为空SELECT B FROM TABLE WHERE A ISNULL
IN属于运算判断一个值是否为列表中的任意一个值SELECT D FROM TABLE WHERE C IN (A, B)
NOT IN不属于运算判断一个值是否不是一个列表中的任意一个值SELECT D FROM TABLE WHERE C NOT IN (A,B)
LIKE模糊匹配运算判断一个值是否符合模糊匹配规则SELECT C FROM TABLE WHERE A LIKE B
REGEXP正则表达式运算判断一个值是否符合正则表达式的规则SELECT C FROM TABLE WHERE A REGEXP B
RLIKE正则表达式运算判断一个值是否符合正则表达式的规则(同义词)SELECT C FROM TABLE WHERE A RLIKE B

4.1 为空运算符

IS NULL或者ISNULL判断一个值是否为NULL, 如果为NULL则返回1, 否则返回0.
-- 查询员工表中commission_pct为NULL的员工名字:
mysql> SELECT first_name FROM employees WHERE  commission_pct IS NULL;
+-------------+----------------+
| first_name  | commission_pct |
+-------------+----------------+
| Steven      |           NULL |
| Neena       |           NULL |
| ...         |           ...  | -- 省略
| Hermann     |           NULL |
| Shelley     |           NULL |
| William     |           NULL |
+-------------+----------------+
72 rows in set (0.00 sec)
-- 或者
mysql> SELECT first_name FROM employees WHERE ISNULL(commission_pct);
+-------------+----------------+
| first_name  | commission_pct |
+-------------+----------------+
| Steven      |           NULL |
| Neena       |           NULL |
| ...         |           ...  | -- 省略
| Hermann     |           NULL |
| Shelley     |           NULL |
| William     |           NULL |
+-------------+----------------+
72 rows in set (0.00 sec)

4.2 不为空运算

IS NOT NULL判断一个值是否为NULL, 如果不为NULL则返回1, 否则返回0.
-- 查询员工表中commission_pct为不NULL的员工名字:
mysql> SELECT first_name FROM employees WHERE commission_pct IS NOT NULL;
+-------------+
| first_name  |
+-------------+
| John        |
| ...         | -- 省略
| Kimberely   |
| Charles     |
+-------------+
35 rows in set (0.00 sec)
-- 或 (先判断是否为NULL, 然后取反)
mysql> SELECT first_name FROM employees WHERE NOT commission_pct <=> NULL;
+-------------+
| first_name  |
+-------------+
| John        |
| ...         | -- 省略
| Kimberely   |
| Charles     |
+-------------+

4.3 最小/大运算符

-- 比较序列中最大的值
mysql> SELECT LEAST('g','b','t','m'), GREATEST('g','b','t','m') FROM DUAL;
+------------------------+---------------------------+
| LEAST('g','b','t','m') | GREATEST('g','b','t','m') |
+------------------------+---------------------------+
| b                      | t                         |
+------------------------+---------------------------+
1 row in set (0.01 sec)

4.4 区间取值

区间取值: 查询的字段 BETWEEN 边界下限 AND 边界上限; 包含边界值.
-- 查询员工表中工资在6000到8000的员工名字.
mysql> SELECT first_name FROM employees WHERE salary BETWEEN 6000 AND 8000;
+-------------+
| first_name  |
+-------------+
| Bruce       |
| Ismael      |
| ...         | -- 省略
| Pat         |
| Susan       |
+-------------+
24 rows in set (0.00 sec)

4.5 属于

-- 查询员工表中部门编号为10, 20, 30的员工姓名和部门id:
mysql> SELECT first_name, department_id FROM employees WHERE 
department_id = 10 OR department_id = 20 OR department_id = 30;
+------------+---------------+
| first_name | department_id |
+------------+---------------+
| Jennifer   |            10 |
| Michael    |            20 |
| Pat        |            20 |
| Den        |            30 |
| Alexander  |            30 |
| Shelli     |            30 |
| Sigal      |            30 |
| Guy        |            30 |
| Karen      |            30 |
+------------+---------------+
9 rows in set (0.01 sec)

mysql> SELECT first_name, department_id FROM employees WHERE department_id IN (10, 20, 30);
+------------+---------------+
| first_name | department_id |
+------------+---------------+
| Jennifer   |            10 |
| Michael    |            20 |
| Pat        |            20 |
| Den        |            30 |
| Alexander  |            30 |
| Shelli     |            30 |
| Sigal      |            30 |
| Guy        |            30 |
| Karen      |            30 |
+------------+---------------+
9 rows in set (0.00 sec)

4.6 不属于

-- 查询员工表中部门编号不是10, 20, 30的员工姓名和部门id:
mysql>  SELECT first_name, department_id FROM employees WHERE department_id NOT IN (10, 20, 30);
+-------------+---------------+
| first_name  | department_id |
+-------------+---------------+
| Steven      |            90 |
| Neena       |            90 |
| ...         |            .. | -- 省略
| Susan       |            40 |
| Hermann     |            70 |
| Shelley     |           110 |
| William     |           110 |
+-------------+---------------+

4.7 模糊查询

在模糊查询中, 有两个人特殊符号:
* 1. 百分号(%): 代表不确定个数的字符(0, 1个或多个).
* 2. 下划线(_): 代表一个不确定的字符.
* 可以在特殊符号前面添加\取消转义; 还可以使用关键字ESCAPE指定取消转义的字符.
-- 查询员工表中包含字符'a'的员工名字.
mysql> SELECT first_name FROM employees WHERE first_name LIKE '%a%';
+-------------+
| first_name  |
+-------------+
| Neena       |
| Alexander   |
| David       |
| Valli       |
| ...         | -- 省略
| Hermann     |
| William     |
+-------------+
70 rows in set (0.00 sec)
-- 查询员工表中名字以'a'开头的员工名字.
mysql> SELECT first_name FROM employees WHERE first_name LIKE 'a%';
+------------+
| first_name |
+------------+
| Alexander  |
| Alexander  |
| Adam       |
| Alberto    |
| Allan      |
| Amit       |
| Alyssa     |
| Alexis     |
| Anthony    |
| Alana      |
+------------+
10 rows in set (0.00 sec)
-- 查询员工表中名字含有字符'a'与字符'e'的员工名字.
mysql> SELECT first_name FROM employees WHERE first_name LIKE '%a%' AND first_name LIKE '%e%';
+-------------+
| first_name  |
+-------------+
| Neena       |
| Alexander   |
| Daniel      |
| ...         | -- 省略
| Michael     |
| Hermann     |
+-------------+
29 rows in set (0.00 sec)

-- 或
mysql> SELECT first_name FROM employees WHERE first_name LIKE '%a%e%' OR first_name LIKE '%e%a%';
+-------------+
| first_name  |
+-------------+
| Neena       |
| Alexander   |
| Daniel      |
| ...         | -- 省略
| Michael     |
| Hermann     |
+-------------+
29 rows in set (0.00 sec)
-- 查询员工表中, 名字的第3个字符是'a'的员工名字:
mysql> SELECT first_name FROM employees WHERE first_name LIKE "__a%";
+------------+
| first_name |
+------------+
| Diana      |
| Adam       |
| Shanta     |
| Clara      |
| Charles    |
| Jean       |
| Alana      |
+------------+
7 rows in set (0.00 sec)
-- 查询职位历史表中(job_history)职位id的第2个字符是_且第3个字符是'A'的职位id:
mysql> SELECT job_id FROM job_history WHERE job_id LIKE '__\_a%';
+------------+
| job_id     |
+------------+
| AC_ACCOUNT |
| AC_ACCOUNT |
| AD_ASST    |
+------------+
3 rows in set (0.00 sec)
-- 使用关键字ESCAPE自定义取消转义符号:
mysql>  SELECT job_id FROM job_history WHERE job_id LIKE '__$_a%' ESCAPE '$';
+------------+
| job_id     |
+------------+
| AC_ACCOUNT |
| AC_ACCOUNT |
| AD_ASST    |
+------------+
3 rows in set (0.00 sec)

4.8 REGEXP运算符

REGEXP运算符用来匹配字符串, 语法格式为: expr REGEXP 匹配条件.
如果expr满足匹配条件, 返回1, 如果不满足, 则返回0.
若expr或匹配条件任意一个为NULL, 则结果为NULL.
REGEXP运算符在进行匹配时, 常用的有下面几种通配符:
* 1. "^": 匹配以该字符后面的字符开头的字符串.
* 2. "$": 匹配以该字符前面的字符结尾的字符串.
* 3. ".": 匹配任何一个单字符.
* 4. "[...]": 匹配在方括号内的任何字符.
     例如, "[abc]"匹配'a''b''c'.
     可以使用一个'-'号设置区间范围. "[a-z]"匹配任何字母, "[0-9]"匹配任何数字.
* 5. "*": 匹配零个或多个在它前面的字符.
     例如, "x*"匹配任何数量的"x"字符, "[0-9]*"匹配任何数量的数字, ".*"匹配任何数量的任何字符, 包括空字符串.
-- 匹配员工表中名字以A开头的员工名字:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '^a';
+------------+
| first_name |
+------------+
| Alexander  |
| Alexander  |
| ...        |
| Alexis     |
| Anthony    |
| Alana      |
+------------+
10 rows in set (0.02 sec)
-- 匹配员工表中名字以r结尾的员工名字:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'r$';
+-------------+
| first_name  |
+-------------+
| Alexander   |
| Alexander   |
| ...         |
| Tayler      |
| Jennifer    |
| Jennifer    |
+-------------+
11 rows in set (0.00 sec)

5. 逻辑运算

逻辑运算:
* 1. 逻辑与 AND (&&): 当两个布尔值同时为true,返回true; 否则, 返回false.
* 2. 逻辑或 OR  (||): 当两个布尔值中至少一个为true, 返回true; 否则, 返回false.
* 3. 逻辑非 NOT (!) : 对单个布尔值进行取反操作, 即将true变为false, false变为true.
* 4. 逻辑异或 XOR   : 当两个布尔值一个为true, 一个为false, 返回true.
     如果两个布尔值相同, 即都为true或都为false, 异或操作返回false.
     
以下是AND, OR, NOT和XOR四种逻辑运算的真值表格:
ABAND (A && B)OR (A || B)NOT (!A)XOR (A ^ B)
truetruetruetruefalsefalse
truefalsefalsetruefalsetrue
falsetruefalsetruetruetrue
falsefalsefalsefalsetruefalse
-- 查询员工表中, 部门id为10或者20的员工名字和部门id:
mysql> SELECT first_name, department_id FROM employees WHERE department_id = 10 OR department_id = 20;
+------------+---------------+
| first_name | department_id |
+------------+---------------+
| Jennifer   |            10 |
| Michael    |            20 |
| Pat        |            20 |
+------------+---------------+
3 rows in set (0.03 sec)
-- 查询员工表中, 部门id为50 并且工资为50的员工名字, 工资, 部门id:
mysql> SELECT first_name, salary, department_id FROM employees WHERE department_id = 50 AND salary > 6000;
+------------+---------+---------------+
| first_name | salary  | department_id |
+------------+---------+---------------+
| Matthew    | 8000.00 |            50 |
| Adam       | 8200.00 |            50 |
| Payam      | 7900.00 |            50 |
| Shanta     | 6500.00 |            50 |
+------------+---------+---------------+
4 rows in set (0.00 sec)
-- 查询员工表中, 工资不在6000 - 8000 之间的员工名字, 工资:
mysql> SELECT first_name, salary FROM employees WHERE salary NOT BETWEEN 6000 AND 8000;
+------------+----------+
| first_name | salary   |
+------------+----------+
| Steven     | 24000.00 |
| Neena      | 17000.00 |
| Lex        | 17000.00 |
| ...        |      ... | -- 省略
| Jennifer   |  4400.00 |
| Michael    | 13000.00 |
| Hermann    | 10000.00 |
| Shelley    | 12000.00 |
| William    |  8300.00 |
+------------+----------+
83 rows in set (0.00 sec)
-- 查询员工表中, 佣金提成不为NULL的员工名字, 佣金提成:
-- SELECT first_name, commission_pct FROM employees WHERE commission_pct IS NOT NULL;
mysql> SELECT first_name, commission_pct FROM employees WHERE NOT commission_pct <=> NULL;
+-------------+----------------+
| first_name  | commission_pct |
+-------------+----------------+
| John        |           0.40 |
| Karen       |           0.30 |
| Alberto     |           0.30 |
| Gerald      |           0.30 |
| ...         |            ... | -- 省略
| Alyssa      |           0.25 |
| Jonathon    |           0.20 |
| Jack        |           0.20 |
| Kimberely   |           0.15 |
| Charles     |           0.10 |
+-------------+----------------+
35 rows in set (0.00 sec)
-- 异或两种情况:
* 1. 部门id为50,   则工资小于6000.
* 2. 部门id不为50, 则工资大于6000.
mysql> SELECT first_name, department_id, salary FROM employees WHERE department_id = 50 XOR salary > 6000;
+-------------+---------------+----------+
| first_name  | department_id | salary   |
+-------------+---------------+----------+
| Steven      |            90 | 24000.00 |
| ...         |            .. |      ... | -- 省略
| Alana       |            50 |  3100.00 |
| Kevin       |            50 |  3000.00 |
| Donald      |            50 |  2600.00 |
| Douglas     |            50 |  2600.00 |
| Michael     |            20 | 13000.00 |
| Susan       |            40 |  6500.00 |
| Hermann     |            70 | 10000.00 |
| Shelley     |           110 | 12000.00 |
| William     |           110 |  8300.00 |
+-------------+---------------+----------+

5. 位运算

运算符描述示例
&按位与对两个数字的对应位执行与运算.
|按位或对两个数字的对应位执行或运算.
^按位异或对两个数字的对应位执行异或运算.
~按位取反对一个数字的每个位取反.
>>右移将数字的二进制表示向右移动指定位数.
<<左移将数字的二进制表示向左移动指定位数.
mysql> SELECT 12 & 5, 12 | 5, 12 ^ 5 FROM DUAL;
+--------+--------+--------+
| 12 & 5 | 12 | 5 | 12 ^ 5 |
+--------+--------+--------+
|      4 |     13 |      9 |
+--------+--------+--------+
1 row in set (0.00 sec)
十进制: 12 --> 二进制: 1 1 0 0   十进制: 12 --> 二进制: 1 1 0 0   十进制: 12 --> 二进制: 1 1 0 0  
十进制:  5 --> 二进制: 0 1 0 1   十进制:  5 --> 二进制: 0 1 0 1   十进制:  5 --> 二进制: 0 1 0 1
与计算: --一一得一-------------  或计算: --有一得一-------------   异或计算:--一零得一-----------
十进制:  4 <-- 二进制: 0 1 0 0   十进制: 13 <-- 二进制: 1 1 0 1    十进制: 9 <-- 十进制: 1 0 0 1
mysql> SELECT  ~1 FROM DUAL;
+----------------------+
| ~1                   |
+----------------------+
| 18446744073709551614 |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT 10 & ~1 FROM DUAL;
+---------+
| 10 & ~1 |
+---------+
|      10 |
+---------+
1 row in set (0.00 sec)
数字1:  0000000000000000000000000000000000000000000000000000000000000001,
1取反:  1111111111111111111111111111111111111111111111111111111111111110. (18446744073709551614)
数字10: 0000000000000000000000000000000000000000000000000000000000001010,
与运算: ----------------------------------------------------------------
数字10: 0000000000000000000000000000000000000000000000000000000000001010.
-- 在一定范围内满足: 每向左移动1位, 相当于乘以2; 每向右移动一位, 相当于除以2.
mysql> SELECT 4 << 1 , 8 >> 1 FROM DUAL;
+--------+--------+
| 4 << 1 | 8 >> 1 |
+--------+--------+
|      8 |      4 |
+--------+--------+
1 row in set (0.00 sec)

6. 运算符优先级

优先级运算符描述
1:=, =(赋值)赋值操作符.
2OR(||), XOR逻辑或, 逻辑异或.
3AND(&&)逻辑与操作符.
4NOT逻辑非操作符.
5BETWEEN, CASE, WHEN, THEN, ELSEBETWEEN, CASE, WHEN, ELSE操作符.
6= (比较运算符), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN比较运算符和模式匹配操作符.
7|按位或操作符.
8&按位与操作符.
9<<, >>左位移, 右位移操作符.
10-, +减法, 加法操作符.
11\*, /, DIV, %, MOD乘法, 除法, 整数除法, 取余操作符.
12^按位异或操作符.
13-(负号), ~(按位取反)一元负号, 一元按位取反操作符.
14!逻辑非操作符(部分MySQL版本中支持).
15()括号, 改变运算符的优先级.
请注意, 表格中较高的优先级的运算符会优先进行计算, 而较低优先级的运算符则会在较高优先级运算符计算完毕后进行.
括号可以用于改变运算符的优先级.

7. 正则表达式查询

正则表达式通常被用来检索或替换那些符合某个模式的文本内容, 根据指定的匹配模式匹配文本中符合要求的特殊字符串.
例如: 从一个文本文件中提取电话号码, 查找一篇文章中重复的单词或者替换用户输入的某些敏感词语等,
这些地方都可以使用正则表达式; 正则表达式强大而且灵活,可以应用于非常复杂的查询.
MySQL中使用REGEXP关键字指定正则表达式的字符匹配模式.

下表列出了REGEXP操作符中常用字符匹配列表:
选项说明例子示例
^匹配以指定字符开头的字符串.'^b': 匹配以字母 b 开头的字符串.book, big, bababa, bike
$匹配以指定字符结尾的字符串.'st$': 匹配以 st 结尾的字符串.test, resist, persist
.匹配任何单个字符.'b.t': 匹配任何b和t之间有一个字符的字符串.bit, bat, but, bite
*匹配前面的字符0次或更多次.'f*n': 匹配字符 n 前面有任意个字符 f 的字符串.fn, fan, faan, fabcn
+匹配前面的字符至少1次或多次.'ba+': 匹配以b开头后面紧跟至少有一个a的字符串ba, bay, bare, battle
<字符串>匹配包含指定字符串的文本.'fa': 匹配包含fa的字符串fan, afa, faad
[字符集合]匹配字符集合中的任何一个字符.'[xa]': 匹配包含x或者z的字符串.dizzy, zebra, x-ray, extra
[^ ]匹配不在指定字符集合中的任何字符.'[^abc]': 匹配任何不包含a, b, c的字符串.desk, fox, f8ke
字符串{n,}匹配前面的字符串至少n次.'b{n}': 匹配2个或更多的b.bbb, bbbb, bbbbbb
字符串{n,m}匹配前面的字符串至少n次, 至多m次.'b{2, 4}': 匹配含最少2个, 最多4个的b的字符串.bb, bbb, bbbb
如果n为0, 此表达式为可选.a{0,3}: a可以出现0, 1, 2, 3次, 即整个表达式是可选的.无, a, aa, aaa
* 1. 查询以特定字符或字符串开头的记录字符'^'匹配以特定字符或者字符串开头的文本.
     查询员工表中, 名字以字母'b'开头的员工名字, SQL语句如下:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '^b';
+------------+
| first_name |
+------------+
| Bruce      |
| Britney    |
+------------+
2 rows in set (0.02 sec)
* 2. 查询以特定字符或字符串结尾的记录字符'$'匹配以特定字符或者字符串结尾的文本.
     查询员工表中, 名字以字母't'结尾的员工名字, SQL语句如下:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP 't$';
+------------+
| first_name |
+------------+
| Amit       |
| Pat        |
+------------+
2 rows in set (0.00 sec)
* 3. 用符号"."来替代字符串中的任意一个字符, 字符'.'匹配任意一个字符.
     查询员工表中, 名字中有字母'a''c'且两个字母之间只有一个字母的员工名字, SQL语句如下:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'a.c';
+------------+
| first_name |
+------------+
| Nancy      |
| Vance      |
+------------+
2 rows in set (0.00 sec)
* 4. 使用"*""+"来匹配多个字符; 星号'*'匹配前面的字符任意多次, 包括0. 加号'+'匹配前面的字符至少一次.
     查询员工表中, 名字以字母'b'开头且后面会出现字母'e'的员工名字, SQL语句如下:
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '^b.*e+.*';
+------------+
| first_name |
+------------+
| Bruce      |
| Britney    |
+------------+
2 rows in set (0.00 sec)

* 5. 匹配指定字符串, 正则表达式可以匹配指定字符串, 只要这个字符串在查询文本中即可,
     如要匹配多个字符串, 多个字符串之间使用分隔符'|'隔开.
     1. 查询员工表中, 名字中有字符'it'的员工名字; 
     2. 查询员工表中, 名字中有字符'it''ii'的员工名字;
mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'it';
+------------+
| first_name |
+------------+
| Amit       |
| Sundita    |
| Nandita    |
| Britney    |
+------------+
4 rows in set (0.00 sec)

mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'it|ic';
+------------+
| first_name |
+------------+
| Michael    |
| Patrick    |
| Amit       |
| Sundita    |
| Nandita    |
| Britney    |
| Michael    |
+------------+
7 rows in set (0.00 sec)
在一般情况下, LIKE和REGEXP操作符都可以用于匹配指定的字符串.
它们之间的主要区别在于匹配方式和规则的不同.
* 1. LIKE操作符是基于模式匹配的, 使用通配符%和_来匹配任意字符和单个字符.
     当使用LIKE进行匹配时, 如果要匹配的字符串出现在文本的中间, 它不会被找到并返回相应的行.

* 2. REGEXP操作符是基于正则表达式匹配的, 可以执行更复杂和灵活的模式匹配.
     当使用REGEXP进行匹配时, 如果要匹配的字符串在文本中间出现, 它可以被找到并返回相应的行.
mysql> SELECT first_name FROM employees WHERE first_name LIKE 'it';
Empty set (0.01 sec)

mysql> SELECT first_name FROM employees WHERE first_name LIKE '%it%';
+------------+
| first_name |
+------------+
| Amit       |
| Sundita    |
| Nandita    |
| Britney    |
+------------+
4 rows in set (0.00 sec)
* 6. 匹配指定字符中的任意一个, 方括号'[]'指定一个字符集合, 只匹配其中任何一个字符, 即为所查找的文本.
     查询员工表中, 名字中有字符'a''i'的员工名字;
-- 字符串格式中指定匹配的字符组, 中括号中指定匹配的单个字符.
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '[ai]';
+-------------+
| first_name  |
+-------------+
| Neena       |
| Alexander   |
| David       |
| ...         | --省略
| William     |
+-------------+
88 rows in set (0.00 sec)
* 7. 匹配指定字符以外的字符, "[^字符集合]"匹配不在指定集合中的任何字符.
     查询员工表中, 名字中不包含字符'a-i'的员工名字;
-- [^]匹配的字符中如果有一个字符不在他的排除范围就能匹配成功!!!
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '[^a-e]';
+-------------+
| first_name  |
+-------------+
| Steven      |
| Neena       |
| Tayler      |
| ...         | --省略
| William     |
+-------------+
107 rows in set (0.00 sec)

-- 对于严格排除包含指定字符范围的名字, 可以使用其他方法, 例如使用正则表达式的边界匹配(如^和$).
mysql> SELECT first_name FROM employees WHERE first_name REGEXP '^[^a-e]+$';
+------------+
| first_name |
+------------+
| John       |
| Luis       |
| Guy        |
| TJ         |
| Ki         |
| John       |
| John       |
| Winston    |
| Timothy    |
+------------+
9 rows in set (0.00 sec)

-- '^[^a-e]+$': 这个正则表达式表示匹配整个字符串, 该字符串中的每一个字符都不是小写字母'a'到'e'.
-- 这里的+表示前面的字符类([^a-e])可以出现一次或多次.
-- 因此, 这个正则表达式会匹配任何完全由不在'a'到'e'范围内的字符组成的字符串.
* 8. 使用{n,}或者{n,m}来指定字符串连续出现的次数.
     "字符串{n,}"表示至少匹配n次前面的字符; "字符串{n,m}"表示匹配前面的字符串不少于n次, 不多于m次.
     例如, a{2,}表示字母a连续出现至少2, 也可以大于2; a{2,4}表示字母a连续出现最少2, 最多不能超过4.
     查询员工表中, 名字中字符'e'出现2-3次的员工名字;
-- 注意: 不要在逗号和数字之间加空格.
mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'e{2, 3}';
ERROR 3692 (HY000): Incorrect description of a {min,max} interval.

mysql> SELECT first_name FROM employees WHERE first_name REGEXP 'e{2,3}';
+------------+
| first_name |
+------------+
| Neena      |
+------------+
1 rows in set (0.00 sec)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/107937.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AJAX原理及介绍

文章目录 AJAX&#xff08;Asynchronous Javascript And Xml&#xff09;传统请求及缺点AJAX概述XMLHttpRequest对象AJAX GET请求AJAX GET请求的缓存问题AJAX POST请求基于JSON的数据交换基于XML的数据交换AJAX乱码问题AJAX的异步与同步AJAX代码封装AJAX实现省市联动AJAX跨域问…

磁盘的结构(磁道,扇区,盘面,柱面,物理地址)

目录 1.磁盘、磁道、扇区的概念1.磁盘2.磁道3.扇区 2.如何在磁盘中读/写数据3.盘面、柱面的概念4.磁盘的物理地址1.根据地址读取一个“块” 5.磁盘的分类1.活动头磁道2.固定头磁盘3.根据盘片是否可更换 1.磁盘、磁道、扇区的概念 1.磁盘 磁盘的表面由一些磁性物质组成&#xf…

打破尺寸记录!荷兰QuTech研发16量子点阵列新技术

承载16个量子点交叉条阵列的量子芯片&#xff0c;可无缝集成到棋盘图案&#xff08;图片来源&#xff1a;网络&#xff09; 由荷兰代尔夫特理工大学(TU Delft)和荷兰应用科学研究组织(TNO)组建的荷兰量子计算研究中心QuTech的研究人员开发了一种用相对较少的控制线来控制大量量…

双向链表的初步练习

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇: Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”…

Redis进军磁盘存储

目录 1、对抗价格优势&#xff1a;纳入磁盘&#xff0c;降低成本&#xff1f; 2、Redis的野心&#xff1a;无敌是多么寂寞&#xff0c;所以我们要开新地图 3、开发者异议&#xff1a;他们正在偏离我们选择Redis的初衷 4、结语&#xff1a;性能为王&#xff0c;但绝不甘于只…

Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)

这篇博客是之前文章&#xff1a; Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;一&#xff09;Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;二&a…

ROS自学笔记十八:ModuleNotFoundError: No module named ‘serial‘

出现上述错误&#xff0c;则需要安装serial功能包 第一步&#xff1a;输入 sudo apt install python3-pip 第二步&#xff1a;输入 pip install pyserial

List 3.5 详解原码、反码、补码

前言 欢迎来到我的博客&#xff0c;我是雨空集&#xff08;全网同名&#xff09;&#xff0c;无论你是无意中发现我&#xff0c;还是有意搜索而来&#xff0c;我都感到荣幸。这里是一个分享知识、交流想法的平台&#xff0c;我希望我的博客能给你带来帮助和启发。如果你喜欢我…

记一次线程爆满导致服务器崩溃的问题排查

记一次线程爆满导致服务器崩溃的问题排查 重启服务器 重启后&#xff0c;ssh连接发现下面问题 fork faild:Cannot allocate memory 以为是内存满了 于是&#xff0c;free -h,查看内存情况&#xff0c;还有&#xff0c;观察一段时间后&#xff0c;内存没多大变化 修改…

【扩散模型】HuggingFace Diffusers实战

HuggingFace Diffusers实战 1. 环境准备2. DreamBooth2.1 Stable Diffusion简介2.2 DreamBooth 3. Diffusers核心API4. 实战&#xff1a;生成美丽的蝴蝶图像4.1 下载数据集4.2 调度器4.3 定义扩散模型4.4 创建扩散模型训练循环4.5 图像的生成方法1.建立一个管线方法2.写一个采样…

MySQL 字符集与乱码与collation设置的问题?

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友…

线扫相机DALSA--常见问题一:软件安装顺序

1.软件安装顺序 先安装&#xff1a;Sapera_LT_SDK&#xff0c;后安装Xtium-CL MX4驱动。 2.初次安装CamExpert&#xff0c;重启电脑后未找到相机 Settings(搜索协议)配置完毕后&#xff0c;需点击Detect Camera(一键查找相机)按钮&#xff0c;搜索相机。第一次查找相机耗时会略…

word行内插入mathtype 公式后行距变大解决办法

现象 word行内插入mathtype 公式后行距变大 解决方法 选中要进行操作的那些行&#xff0c;依次单击菜单命令“格式→段落”&#xff0c;打开“段落”对话框&#xff1b;单击“缩进和间距”选项卡&#xff0c;将间距的“段前”和“段后”都调整为“0行”&#xff1b;将“如果…

【广州华锐互动】城市水处理VR仿真实训平台

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为我们带来了前所未有的沉浸式体验。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为传统的教学模式带来了革命性的变革。本文将以城市水处理VR仿真实训…

Java集合类--List集合,Set集合,Map集合

集合可以看作一个容器&#xff0c;Java中提供了不同的集合类&#xff0c;这些类具有不同的存储对象的方式&#xff0c;同时提供了相应的方法&#xff0c;以便用户对集合进行遍历、添加、删除、查找指定的对象。 1.集合类概述&#xff1a; 集合类类似于数组&#xff0c;与数组不…

公网远程访问macOS本地web服务器

# 公网访问macOS本地web服务器【内网穿透】 文章目录 1. 启动Apache服务器2. 公网访问本地web服务2.1 本地安装配置cpolar2.2 创建隧道2.3 测试访问公网地址3. 配置固定二级子域名3.1 保留一个二级子域名3.2 配置二级子域名4. 测试访问公网固定二级子域名 以macOS自带的Apache…

局域网内两台电脑共享文件夹(通过网线直连共享数据)

文章目录 2.设置共享文件夹3.访问共享文件夹 1.将两台电脑置于同一局域网下 用网线将两台电脑连接关闭两台电脑防火墙将两台电脑IP地址设置在同一局域网下 测试是否在同一局域网下&#xff0c;使用ping命令 ping 192.168.0.122.设置共享文件夹 选择想要共享的文件夹&#xff…

基于单片机的智能电子鼻的设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、智能电子鼻系统的设计方案1.1智能电子鼻系统的设计思路1.2智能电子鼻系统的设计流程图1.3智能电子鼻系统的硬件数…

Android系统的特性

目录 Android系统的特性 1. 显示布局 2. 数据存储 3. 网络 4. 信息 5. 浏览器 6. 编程语言支持 7. 媒体支持 8. 流媒体支持 9. 硬件支持 10. 多点触控 11.蓝牙 12. 多任务处理 13. 语音功能 14.无线共享功能 15. 截图功能 16. 跨平台 17. 应用程序的安全机制…

IT行业变成了夕阳行业

IT技术发展背景及历程 从2010年左右开始&#xff0c;大众创新&#xff0c;万众创业变成了一个经常看到的词语&#xff0c;在创业潮的带动下&#xff0c;同时刚好赶上了互联网的高速发展&#xff0c;一大批互联网创业公司应运而生&#xff0c;在这样的背景下&#xff0c;IT行业…