1. 位运算符
- 位运算符是在二进制数上进行计算的运算符。位运算符会先将操作数变成二进制数,然后进行位运算,最后将计算结果从二进制变回十进制数。
- MySQL支持的位运算符如下:
1.1 按位与运算符
- 按位与(
&
)运算符将给定值对应的二进制数逐位进行逻辑与运算。当给定值对应的二进制位的数值都为1时,则该位返回1,否则返回0。
mysql> SELECT 1 & 10, 20 & 30;
+--------+---------+
| 1 & 10 | 20 & 30 |
+--------+---------+
| 0 | 20 |
+--------+---------+
1 row in set (0.00 sec)
- 1的二进制数为0001,10的二进制数为1010,所以1 & 10的结果为0000,对应的十进制数为0。20的二进制数为10100,30的二进制数为11110,所以20 & 30的结果为10100,对应的十进制数为20。
1.2 按位或运算符
- 按位或(
|
)运算符将给定的值对应的二进制数逐位进行逻辑或运算。当给定值对应的二进制位的数值有一个或两个为1时,则该位返回1,否则返回0。
mysql> SELECT 1 | 10, 20 | 30;
+--------+---------+
| 1 | 10 | 20 | 30 |
+--------+---------+
| 11 | 30 |
+--------+---------+
1 row in set (0.00 sec)
- 1的二进制数为0001,10的二进制数为1010,所以1 | 10的结果为1011,对应的十进制数为11。20的二进制数为10100,30的二进制数为11110,所以20 | 30的结果为11110,对应的十进制数为30。
1.3 按位异或运算符
- 按位异或(^)运算符将给定的值对应的二进制数逐位进行逻辑异或运算。当给定值对应的二进制位的数值不同时,则该位返回1,否则返回0。
mysql> SELECT 1 ^ 10, 20 ^ 30;
+--------+---------+
| 1 ^ 10 | 20 ^ 30 |
+--------+---------+
| 11 | 10 |
+--------+---------+
1 row in set (0.00 sec)
- 1的二进制数为0001,10的二进制数为1010,所以1 ^ 10的结果为1011,对应的十进制数为11。20的二进制数为10100,30的二进制数为11110,所以20 ^ 30的结果为01010,对应的十进制数为10。
- 举例:
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)
1.4 按位取反运算符
- 按位取反(~)运算符将给定的值的二进制数逐位进行取反操作,即将1变为0,将0变为1。
mysql> SELECT 10 & ~1;
+---------+
| 10 & ~1 |
+---------+
| 10 |
+---------+
1 row in set (0.00 sec)
- 由于按位取反(~)运算符的优先级高于按位与(&)运算符的优先级,所以10 & ~1,首先,对数字1进行按位取反操作,结果除了最低位为0,其他位都为1,然后与10进行按位与操作,结果为10。
1.5 按位右移运算符
- 按位右移(>>)运算符将给定的值的二进制数的所有位右移指定的位数。右移指定的位数后,右边低位的数值被移出并丢弃,左边高位空出的位置用0补齐。
mysql> SELECT 1 >> 2, 4 >> 2;
+--------+--------+
| 1 >> 2 | 4 >> 2 |
+--------+--------+
| 0 | 1 |
+--------+--------+
1 row in set (0.00 sec)
- 1的二进制数为0000 0001,右移2位为0000 0000,对应的十进制数为0。4的二进制数为0000 0100,右移2位为0000 0001,对应的十进制数为1。
1.6 按位左移运算符
- 按位左移(<<)运算符将给定的值的二进制数的所有位左移指定的位数。左移指定的位数后,左边高位的数值被移出并丢弃,右边低位空出的位置用0补齐。
mysql> SELECT 1 << 2, 4 << 2;
+--------+--------+
| 1 << 2 | 4 << 2 |
+--------+--------+
| 4 | 16 |
+--------+--------+
1 row in set (0.00 sec)
- 1的二进制数为0000 0001,左移两位为0000 0100,对应的十进制数为4。4的二进制数为0000 0100,左移两位为0001 0000,对应的十进制数为16。
2. 运算符的优先级
- 数字编号越大,优先级越高,优先级高的运算符先进行计算。可以看到,赋值运算符的优先级最低,使用“()”括起来的表达式的优先级最高。
3. 练习
- 选择工资不在5000到12000的员工的姓名和工资
SELECT last_name,salary
FROM employees
#where salary not between 5000 and 12000;
WHERE salary < 5000 OR salary > 12000;
- 选择在20或50号部门工作的员工姓名和部门号
SELECT last_name,department_id
FROM employees
# where department_id in (20,50);
WHERE department_id = 20 OR department_id = 50;
- 选择公司中没有管理者的员工姓名及job_id
SELECT last_name,job_id
FROM employees
WHERE manager_id IS NULL;
SELECT last_name,job_id,manager_id
FROM employees
WHERE manager_id <=> NULL;
- 选择公司中有奖金的员工姓名,工资和奖金级别
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct IS NOT NULL;
SELECT last_name,salary,commission_pct
FROM employees
WHERE NOT commission_pct <=> NULL;
- 选择员工姓名的第三个字母是a的员工姓名
SELECT last_name
FROM employees
WHERE last_name LIKE '__a%';
- 选择姓名中有字母a和k的员工姓名
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%k%' OR last_name LIKE '%k%a%';
#where last_name like '%a%' and last_name LIKE '%k%';
- 显示出表 employees 表中 first_name 以 'e'结尾的员工信息
SELECT first_name,last_name
FROM employees
WHERE first_name LIKE '%e';
SELECT first_name,last_name
FROM employees
WHERE first_name REGEXP 'e$'; # 以e开头的写法:'^e'
- 显示出表 employees 部门编号在 80-100 之间的姓名、工种
SELECT last_name,job_id
FROM employees
#方式1:推荐
WHERE department_id BETWEEN 80 AND 100;
#方式2:推荐,与方式1相同
#where department_id >= 80 and department_id <= 100;
#方式3:仅适用于本题的方式。
#where department_id in (80,90,100);
- 显示出表 employees 的 manager_id 是 100,101,110 的员工姓名、工资、管理者id
SELECT last_name,salary,manager_id
FROM employees
WHERE manager_id IN (100,101,110);