运算符
假如我们有一张表,表名为 scores,如下所示:
+------------+---------+------+---------+
| student_id | chinese | math | english |
+------------+---------+------+---------+
| 1 | 80 | 85.5 | 78 |
| 2 | 88 | 90 | 85 |
| 3 | 92 | 75 | 80 |
| 4 | 78 | 88 | 92 |
| 5 | 85 | 92 | 87 |
| 6 | 90 | 78 | 84 |
| 7 | 86 | 85 | 89 |
| 8 | 79 | 90 | 83 |
| 9 | 82 | 82 | 80 |
| 10 | 88 | 87.5 | 85 |
+------------+---------+------+---------+
算术运算符
在 SQL 中,算术运算符用于执行基本的算术操作,如加法、减法、乘法和除法。这些运算符可以用于对数字列进行计算,并且在 select
语句中非常有用。
-
加法运算符 (
+
):select student_id, chinese + math + english as total_score from scores; +------------+-------------+ | student_id | total_score | +------------+-------------+ | 1 | 243.5 | | 2 | 263 | | 3 | 247 | | 4 | 258 | | 5 | 264 | | 6 | 252 | | 7 | 260 | | 8 | 252 | | 9 | 244 | | 10 | 260.5 | +------------+-------------+ 10 rows in set (0.00 sec)
这条查询将每个学生的语文、数学和英语成绩相加,得出每个学生的总成绩。
-
减法运算符 (
-
):select student_id, math - chinese as math_chinese_difference from scores; +------------+-------------------------+ | student_id | math_chinese_difference | +------------+-------------------------+ | 1 | 5.5 | | 2 | 2 | | 3 | -17 | | 4 | 10 | | 5 | 7 | | 6 | -12 | | 7 | -1 | | 8 | 11 | | 9 | 0 | | 10 | -0.5 | +------------+-------------------------+ 10 rows in set (0.00 sec)
这条查询将每个学生的数学成绩减去语文成绩,得出数学成绩与语文成绩之间的差值。
-
乘法运算符 (
*
):select student_id, chinese * math as chinese_math_product from scores; +------------+----------------------+ | student_id | chinese_math_product | +------------+----------------------+ | 1 | 6840 | | 2 | 7920 | | 3 | 6900 | | 4 | 6864 | | 5 | 7820 | | 6 | 7020 | | 7 | 7310 | | 8 | 7110 | | 9 | 6724 | | 10 | 7700 | +------------+----------------------+ 10 rows in set (0.00 sec)
这条查询将每个学生的语文成绩乘以数学成绩,得出语文成绩和数学成绩的乘积。
-
除法运算符 (
/
):select student_id, (english / (chinese + math + english)) * 100 as english_percentage from scores; +------------+--------------------+ | student_id | english_percentage | +------------+--------------------+ | 1 | 32.03285420944558 | | 2 | 32.31939163498099 | | 3 | 32.388663967611336 | | 4 | 35.65891472868217 | | 5 | 32.95454545454545 | | 6 | 33.33333333333333 | | 7 | 34.23076923076923 | | 8 | 32.93650793650794 | | 9 | 32.78688524590164 | | 10 | 32.629558541266796 | +------------+--------------------+ 10 rows in set (0.00 sec)
这条查询将每个学生的英语成绩除以总成绩,然后乘以100,得出英语成绩占总成绩的百分比。
那么多小数看着很不爽?
select student_id, round((english / (chinese + math + english)) * 100, 2) as english_percentage from scores; +------------+--------------------+ | student_id | english_percentage | +------------+--------------------+ | 1 | 32.03 | | 2 | 32.32 | | 3 | 32.39 | | 4 | 35.66 | | 5 | 32.95 | | 6 | 33.33 | | 7 | 34.23 | | 8 | 32.94 | | 9 | 32.79 | | 10 | 32.63 | +------------+--------------------+ 10 rows in set (0.00 sec)
这里使用
round
函数将结果保留两位小数,简单提一下,后面再做详细的解释。
比较运算符
比较运算符是在 SQL 中用于比较两个值的运算符,它们会产生一个布尔值(True 或 False),用于条件判断。SQL中常用的比较运算符包括:
- 等于 (
=
):检查两个值是否相等。 - 不等于 (
!=
或<>
):检查两个值是否不相等。 - 大于 (
>
):检查一个值是否大于另一个值。 - 小于 (
<
):检查一个值是否小于另一个值。 - 大于等于 (
>=
):检查一个值是否大于或等于另一个值。 - 小于等于 (
<=
):检查一个值是否小于或等于另一个值。
下面就简单的介绍几个常用的,其他的用法也类似:
-
找出数学成绩高于语文成绩的学生:
select student_id, math, chinese from scores where math > chinese; +------------+------+---------+ | student_id | math | chinese | +------------+------+---------+ | 1 | 85.5 | 80 | | 2 | 90 | 88 | | 4 | 88 | 78 | | 5 | 92 | 85 | | 8 | 90 | 79 | +------------+------+---------+ 5 rows in set (0.00 sec)
-
找出英语成绩大于等于 80 分的学生:
select student_id, english from scores where english >= 80; +------------+---------+ | student_id | english | +------------+---------+ | 2 | 85 | | 3 | 80 | | 4 | 92 | | 5 | 87 | | 6 | 84 | | 7 | 89 | | 8 | 83 | | 9 | 80 | | 10 | 85 | +------------+---------+ 9 rows in set (0.00 sec)
-
找出数学成绩不等于 90 分的学生:
select student_id, math from scores where math != 90; +------------+------+ | student_id | math | +------------+------+ | 1 | 85.5 | | 3 | 75 | | 4 | 88 | | 5 | 92 | | 6 | 78 | | 7 | 85 | | 9 | 82 | | 10 | 87.5 | +------------+------+ 8 rows in set (0.00 sec)
逻辑运算符
逻辑运算符用于组合一个或多个逻辑表达式,并生成一个布尔结果。在 SQL 中,常见的逻辑运算符有以下几种:
- AND:当且仅当所有逻辑表达式都为真时,AND 运算结果才为真。
- OR:当任何一个逻辑表达式为真时,OR 运算结果为真。
- NOT:用于否定一个逻辑表达式的结果,如果原表达式为真,则 NOT 运算结果为假,反之亦然。
下面就简单的介绍一下:
-
找出数学成绩大于 80 分且英语成绩大于 85 分的学生:
select student_id, math, english from scores where math > 80 and english > 85; +------------+------+---------+ | student_id | math | english | +------------+------+---------+ | 4 | 88 | 92 | | 5 | 92 | 87 | | 7 | 85 | 89 | +------------+------+---------+ 3 rows in set (0.00 sec)
-
找出语文成绩大于 90 分或英语成绩大于 90 分的学生:
select student_id, chinese, english from scores where chinese > 90 or english > 90; +------------+---------+---------+ | student_id | chinese | english | +------------+---------+---------+ | 3 | 92 | 80 | | 4 | 78 | 92 | +------------+---------+---------+ 2 rows in set (0.00 sec)
-
找出数学成绩不等于 90 分的学生,并且排除掉英语成绩小于 80 分的学生:
select student_id, math, english from scores where math != 90 and not (english < 80); +------------+------+---------+ | student_id | math | english | +------------+------+---------+ | 3 | 75 | 80 | | 4 | 88 | 92 | | 5 | 92 | 87 | | 6 | 78 | 84 | | 7 | 85 | 89 | | 9 | 82 | 80 | | 10 | 87.5 | 85 | +------------+------+---------+ 7 rows in set (0.00 sec)
位运算符
在MySQL中,位运算符是用来对二进制字节中的位进行位移或者测试处理的。以下是MySQL中提供的位运算符
- 按位与(&):如果两个相应的二进制位都为1,则结果为1,否则为0。例如,
1010 & 1001 = 1000
。 - 按位或(|):如果两个相应的二进制位中至少有一个为1,则结果为1,否则为0。例如,
1010 | 1001 = 1011
。 - 按位异或(^):如果两个相应的二进制位值相同,则结果为0,否则为1。例如,
1010 ^ 1001 = 0011
。 - 按位取反(~):对数字的每一位取反。例如,
~1010 = 0101
。 - 左移(<<):将数字的所有位向左移动指定的位数,右边用0填充。例如,
1010 << 1 = 10100
。 - 右移(>>):将数字的所有位向右移动指定的位数。例如,
1010 >> 1 = 101
。
创建一个新的表employee
:
+-------------+---------------+-------------------+
| employee_id | employee_name | permissions_level |
+-------------+---------------+-------------------+
| 1 | Alice | 5 |
| 2 | Bob | 3 |
| 3 | Charlie | 7 |
+-------------+---------------+-------------------+
这里做一下解释:
在位掩码权限系统中,读权限、写权限和执行权限通常用以下数字来表示:
读权限(Read):通常被设置为2的0次方,即1(在二进制中表示为01
)。
写权限(Write):通常被设置为2的1次方,即2(在二进制中表示为10
)。
执行权限(Execute):通常被设置为2的2次方,即4(在二进制中表示为100
)。
-
使用按位与 (
&
) 运算符检查是否具有特定权限:-- 检查是否具有写权限(第二位为 1) select employee_name from employees where permissions_level & 2 = 2; +---------------+ | employee_name | +---------------+ | Bob | | Charlie | +---------------+ 2 rows in set (0.00 sec)
这个查询会返回具有写权限的员工。
这里可能会有同学有疑问,为什么会这样?
where permissions_level & 2 = 2
:这是一个条件语句,只有满足这个条件的记录才会被选择。这里的条件是permissions_level
字段与2进行位与运算的结果必须等于2。这里使用的是位与运算符&
,它会比较permissions_level
和2的二进制表示,只有在同一位置上两者都为1时,结果才为1。例如,如果permissions_level
为6(在二进制中表示为110
),那么与2(在二进制中表示为010
)进行位与运算的结果就是2(在二进制中表示为010
),因此满足条件。举个例子,为什么 7 会满足条件
首先,我们需要将数字7和2转换为二进制形式:
- 7的二进制表示是
111
- 2的二进制表示是
010
然后,我们进行按位与运算(&)。这个运算的规则是:只有当两个相应的二进制位都为1时,结果才为1,否则为0。
所以,我们将这两个二进制数进行按位与运算:
1 1 1 & 0 1 0 -------- 0 1 0
你可以看到,结果是
010
,这在十进制中等于2。所以,7 & 2 = 2
。 - 7的二进制表示是
-
使用按位或 (
|
) 运算符添加特定权限:-- 给所有员工添加读权限(第一位为 1) update employees set permissions_level = permissions_level | 1; Query OK, 0 rows affected (0.00 sec) Rows matched: 3 Changed: 0 Warnings: 0
这个更新语句会将所有员工的权限级别中的第一位设置为 1,即添加了读权限。
-
使用按位异或 (
^
) 运算符切换特定权限:-- 切换第二位权限(写权限)状态 update employees set permissions_level = permissions_level ^ 2 where employee_id = 1; -- 假设 Alice 的权限级别为 5 Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 -- 查看员工的权限是否改变 select * from employees; +-------------+---------------+-------------------+ | employee_id | employee_name | permissions_level | +-------------+---------------+-------------------+ | 1 | Alice | 7 | | 2 | Bob | 3 | | 3 | Charlie | 7 | +-------------+---------------+-------------------+ 3 rows in set (0.00 sec)
这个更新语句会将 Alice 的权限级别中的第二位取反,即切换了写权限的状态。
-
使用按位取反 (
~
) 运算符对整个权限级别进行取反操作:-- 取反权限级别 select employee_name, ~permissions_level as inverted_permissions from employees;
这个查询会对每个员工的权限级别执行按位取反操作。
这里只需要记得
~
是去取反的意思,具体上述权限可在别的课程中进行学习。