MySQL 02 数据处理之查询

1、基础语句

USE

语法:USE 数据库名;
用于启动需要的数据库

SHOW TABLES

语法:SHOW TABLES;
用于查看当前数据库中的所有的表

DESC

语法:DESC 表名;
用于查看表的结构

2、基本SELECT语句

显示表中所有的数据

语法:SELECT * FROM 表名
语句执行的顺序:
⑴ 首先查看表是否存在,如果不存在则报错:
ERROR 1146 (42S02): Table ‘表名’ doesn’t exist
⑵ 其次查看要查询什么列,即SELECT后面的语句。再显示出来
Tips:SELECT可以当作输出语句来使用,语法:
SELECT 要输出的语句;
示例:SELECT ‘abc’;
SELECT 123;

查询部分列

语法:SELECT 列名 FROM 表名;

查询部分行

语法:SELECT * FROM 表名 WHERE 查询条件;

语句的执行顺序:
⑴ 首先查看表是否存在,如果不存在则报错:
ERROR 1146 (42S02): Table ‘表名’ doesn’t exist
⑵ 其次查看要查询什么列,即SELECT后面的语句
⑶ 再查看要查询什么行,即WHERE后面的语句。最后再显示出来

起别名【给查询出的列】

语法:SELECT 列名 AS 别名 FROM 表名;
Tips:
⑴ AS 关键字可以省略,但是列名和别名之间的空格不能省略
⑵ 别名最好用单引号(’)引起来

3、运算符

加号

(+) 其功能只有一个:做数值型的加法运算

例如:SELECT 1 + 2; – 3

注意:
⑴ 不能将列名用+号连接。如果要拼接列的值,应当使用CONCAT函数【见下面6、函数中的CONCAT】
⑵ 如果纯字符串和数值字符串相加,则结果为数值字符串的值。如:SELECT 1 + ‘a’; – 1
⑶ 如果纯字符串和纯字符串相加,则结果为0。如: SELECT ‘a’ + ‘b’; – 0
任何值和null相加结果都为null

4、条件查询

关系运算符

> 大于
< 小于
= 等于
>= 大于等于
<= 小于等于
<> 不等于

例如:
⑴ 查询employees表中,salary大于2000的员工信息
SELECT * FROM employees
WHERE salary > 2000;

⑵ 查询employees表中,salary不等于6000的员工信息
SELECT * FROM employees
WHERE salary <> 6000;

逻辑运算符

AND 和
OR 或
NOT 非
语法:NOT(条件)

例如:
⑴ 查询employees表中,salary在6000和8000之间的员工信息
SELECT * FROM employees
WHERE salary >= 6000 AND salary <= 8000;

⑵ 查询employees表中,salary是5000或9000的员工信息
SELECT * FROM employees
WHERE salary = 5000 OR salary = 9000;

⑶ 查询employees表中,salary在5000以下的员工信息(salary 不是 >= 5000)
SELECT * FROM employees
WHERE NOT(salary >= 5000);

模糊查询

LIKE


LIKE 像xxx,一般和通配符搭配使用
通配符:% 任意0到多个字符
_ 任意单个字符

如果列中的值包含下划线或百分号,则需要使用转义字符。可以使用任意字符充当转义字符,但是需要声明,使用ESCAPE关键字。

示例:
⑴ 查询employees表中last_name第二个字符为%的员工信息
SELECT * FROM employees
WHERE last_name LIKE ‘_ ’;

⑵ 查询employees表中,last_name包含ase的员工信息
SELECT * FROM employees
WHERE last_name LIKE ‘%ase%’;

⑶ 查询employees表中,last_name的第三个字符为a的员工信息
SELECT * FROM employees
WHERE last_name LIKE ‘__a%’;

⑷ 查询employees表中,last_name的第二个字符为_(下划线),最后一个字符为a的员工信息
SELECT * FROM employees
WHERE last_name LIKE ‘$%a’ ESCAPE ‘$’;

BETWEEN…AND

BETWEEN AND 在某个范围内
语法:BETWEEN 值1 AND 值2
注意:值1不能大于值2
即等同于:? >= 值1 AND ? <= 值2
BETWEEN AND的效率要高于关系运算符

示例:
查询employees表中,salary在6000和9000范围内的员工信息
SELECT * FROM employees
WHERE salary BETWEEN 6000 AND 9000;

IN

IN 属于列值中的一个
语法:列名 IN(值1, 值2, …);
即等同于:列名 = 值1 OR 列名 = 值2 OR 列名 = …
IN 的效率要高于关系运算符

示例:
查询employees表中,salary为6000或7000或8000的员工信息
SELECT * FROM employees
WHERE salary IN(6000, 7000, 8000);

NULL

IS NOT NULL 是否不为空
IS NULL 是否为空

示例:
⑴ 查询employees表中,没有bonus(bonus为null的)的员工信息
SELECT * FROM employees
WHERE bonus IS NULL;

⑵ 查询employees表中,含有bonus的员工信息
SELECT * FROM employees
WHERE bonus IS NOT NULL;

DISTINCT

去除重复的值
示例:
查询employees表中,所有的department_id
SELECT DISTINCT department_id
FROM employees;

5、排序查询

语法

SELECT * | 列名 FROM 表名
【WHERER 条件】
ORDER BY 排序的字段 【ASC | DESC】

ASC 升序 【默认是升序,可以省略】
DESC 降序 【不可省略】

可以按照多个字段进行排序,之间用逗号(,)隔开

语句的执行顺序:
⑴ 首先查看表是否存在,如果不存在则报错:
ERROR 1146 (42S02): Table ‘表名’ doesn’t exist
⑵ 其次查看要查询什么列,即SELECT后面的语句
⑶ 再查看要查询什么行,即WHERE后面的语句
⑷ 最后看是升序还是降序。再显示出来

特点:
⑴ 可以按单个字段排序
⑵ 也可以按多个字段排序
⑶ 可以按表达式排序
⑷ 可以按别名排序
⑸ 可以按函数的返回值排序

ISNULL

函数,判断某个字段或值是否为空,返回值为1【true】或0【false】
语法:ISNULL();

示例:
判断employees表中employee_id为104的员工的bonus是否为空
SELECT ISNULL(bonus) FROM employees
WHERE employee_id = 104;

IFNULL

语法:IFNULL(expr1, expr2)
函数,判断某个字段或值是否为空。要传入两个参数:expr1为要判断的值;expr2为当expr1为空时,作为返回值返回。即如果expr1不为空则返回expr1,如果为空则返回expr2。

示例:
求出employees表中所有员工的年薪
【年薪 = 月工资 * (1 + 奖金率)】
SELECT last_name, (salary * (1 + IFNULL(commission_pct, 0))) AS ‘年薪’
FROM employees;

使用示例

⑴ 查询employees表中所有员工的last_name, salary,并按照salary降序
SELECT last_name, salary
FROM employees
ORDER BY salary DESC;

⑵ 查询employees表中所有员工的last_name,salary,并先按照last_name升序,再按照salary降序
SELECT last_name, salary
FROM employees
ORDER BY last_name, salary DESC;

6、函数

单行函数

传入一个数值,最终得到一个结果

字符函数


LOWER


语法:LOWER(str)
转换为小写

示例:SELECT LOWER(‘Hello MySQL!’); – hello mysql!

UPPER


语法:UPPER(str)
转换为大写

示例:SELECT UPPER(‘Hello MySQL!’); – HELLO MYSQL!

CONCAT

语法:CONCAT(str1, str2, …)
连接多个字符,参数之间用逗号隔开

示例:查询employees表中所有员工的姓名
SELECT CONCAT(last_name, ’ ‘, first_name) AS ‘姓名’
FROM employees

SUBSTR

⑴ 语法:SUBSTR(str, pos)
截取字符,从索引位置处一直到最后都截取出来
注意:索引从1开始

示例:
SELECT SUBSTR(‘Hello MySQL!’, 7); – MySQL!

⑵ 语法:SUBSTR(str, pos, len)
截取字符,从索引位置处,截取指定长度
注意:索引从1开始

示例:
SELECT SUBSTR(‘Hello MySQL!’, 9, 3); – SQL

LENGTH

语法:LENGTH(str)
获取字节长度
注意:获取到的字符长度和当前数据库的字符编码有关【主要是汉字的字节长度不一定】

示例:
SELECT LENGTH(‘你好 MySQL!’); – 6 + 1 + 6 = 13
解释:当前数据库的字符编码为utf8,一个汉字占3个字节,两个汉字共6个字节;1个空格,5个字母,1个感叹号。所以最终为13个字节。
注意:汉字输入的符号所占字节数和汉字所占字节数一致。

INSTR


INSTR(str, substr)
获取字符在指定字符串中的最左边索引。索引从1开始。
示例:
SELECT INSTR(‘Hello MySQL!’, ‘l’); – 3

LPAD


LPAD(str, len, padstr)
用指定的填充字符串,左填充到指定字符串。填充数量为(第二个参数 - 指定字符串长度)。第一个参数为要填充的字符串,第二个参数为填充后的字符串长度。第三个参数为指定的填充字符串。
注意:若第二个参数小于要填充的字符串,则从左开始截取第二个参数的字符。相当于SUBSTR(要填充的字符串, 第二个参数)

示例:
SELECT LPAD(‘abc’, 8, ‘%’); – %%%%%abc
解释:字符串abc的长度为3个字符,第二个设置填充后的字符串长度为8,所以用指定填充字符串%,左填充5(8 - 3)位。

SELECT LPAD(‘abc’, 5, ‘好’); – 好好abc
解释:填充2个字符(5 - 3【abc的长度】),不是按字符的字节数

SELECT LPAD(‘abc’, 2, ‘好’); – ab
解释:第二个参数小于abc的长度,所以截取abc的前两位,即ab

RPAD

RPAD(str, len, padstr)
用指定的填充字符串,右填充到指定字符串。填充数量为(第二个参数 - 指定字符串长度)。第一个参数为要填充的字符串,第二个参数为填充后的字符串长度。第三个参数为指定的填充字符串。
注意:若第二个参数小于要填充的字符串,则从左开始截取第二个参数的字符。相当于SUBSTR(要填充的字符串, 第二个参数)

示例:
SELECT RPAD(‘abcd’, 6,’好’); – abcd好好

SELECT RPAD(‘abcd’, 2,’好’); – ab
解释:第二个参数小于abcd的长度,所以截取abcd的前两位,即ab

TRIM


⑴ TRIM(remstr FROM str)
将remstr中左右两端的str去除。注意FROM关键字不可改变

示例:
SELECT TRIM(’ ’ FROM ’ [ab c de] ‘); – [ab c de]

⑵ TRIM(LEADING remstr FROM str)
将remstr中左端的str去除。注意LEADING关键字和FROM关键字不可改变

示例:
SELECT TRIM(LEADING ‘a’ FROM ‘aaHello MySQLaaa’); – Hello MySQLaaa

⑶ TRIM(TRAILING remstr FROM str)
将remstr中左端的str去除。注意TRAILING关键字和FROM关键字不可改变
示例:
SELECT TRIM(TRAILING ‘a’ FROM ‘aaHello MySQLaaa’); – aaHello MySQL

REPLACE

REPLACE(str, from_str, to_str)
替换

示例:
SELECT REPLACE(‘He110’, ‘110’, ‘LLO’); – HeLLO

数学函数

处理数值型的数据

ROUND

⑴ ROUND(X)
四舍五入,舍掉小数点后面的数

示例:
SELECT ROUND(34.534); – 35

⑵ ROUND(X, D)
四舍五入,舍掉小数点后的指定位数后面的数

示例:
SELECT ROUND(34.534, 2); – 34.53

TRUNCATE


TRUNCATE(X, D)
截断,小数点后的指定位数后面的数

示例:
SELECT TRUNCATE(23.3494, 2); – 23.34

MOD

MOD(n, m)
取余

示例:
SELECT MOD(10, -3); – (1)
SELECT MOD(-5, 2); – (-1)

日期函数


处理日期数据

NOW


NOW()
获取系统时间

示例: SELECT NOW(); – (yyyy-MM-dd hh:mm:ss)

CURDATE

CURDATE()
获取日期

示例: SELECT CURDATE(); – (yyyy-MM-dd)

分组函数

用于做统计的,传入一组值,最终得到一个值

SUM


SUM(expr)
求和

AVG


AVG(expr)
求平均值。该函数忽略NULL值,最终除数的个数也不包括NULL值

MAX

MAX(expr)
求最大值

MIN

MIN(expr)
求最小值

COUNT


COUNT(expr)
统计个数。该函数忽略NULL值

分组函数的特点

⑴ 和分组函数一同查询的列必须是分组后的列(因为它们是一一对应的关系)
⑵ 分组函数的参数一般是列名,只有COUNT()的参数可以为* ,即COUNT(*)
⑶ 所有的分组函数,都忽略NULL值

7、条件表达式

CASE-WHEN-THEN-[ELSE]-END

语法:
CASE 要判断的字段或表达式
WHEN 条件1 THEN 值1
WHEN 条件2 THEN 值2
WHEN 条件3 THEN 值3
ELSE 默认值
END

注意:WHEN后只能写常量值,不能是BETWEEN…AND之类的判断。

示例:查询employees表中department_id为10,20,30的员工信息,若部门号为10,则打印其工资的1.1倍,20号部门,则打印其工资的1.2倍,30号部门打印其工资的1.3倍数。其他为默认值。

SELECT department_id,
CASE department_id
    WHEN 10 THEN salary * 1.1
    WHEN 20 THEN salary * 1.2
    WHEN 30 THEN salary * 1.3
    ELSE salary
END ‘new salary’
FROM employees;

8、分组查询

语法

SELECT 分组函数 | 被分组的列
FROM 表
【WHERE 分组前的条件】
GROUP BY 被分组的列
【HAVING 分组后的条件】

单个字段分组

示例:查询employees表中,每个department的最大salary
SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id;

分组前加筛选条件

分组前的条件:使用WHERE 条件
注意:再次强调:WHERE 的条件不可以使用列的别名

特点:分组前的条件一般可以在原始表(没有分组前的表)中找到

示例:查询employees表中,每个department中last_name包含e的员工的最大salary,department_id,last_name
SELECT MAX(salary), department_id, last_name
FROM employees
WHERE last_name LIKE ‘%e%’
GROUP BY department_id;

分组后加筛选条件

分组后的条件:使用HAVING 条件

特点:⑴ 条件是根据分组后的结果集进行筛选,一般判断的列就是分组函数或分组的列
⑵ 多个分组条件没有先后顺序之说
⑶ 执行顺序:WHERE – GROUP BY – HAVING
⑷ SELECT 列 FROM 表 HAVING 分组前条件
     这条语句也正确,但是效率比WHERE低
⑸ HAVING支持别名做筛选

示例:查询最低salary大于5000的部门的最低工资和department_id

分析:
⑴ 首先要找出各个部门的最低工资,数据不止一个,所以要使用GROUP BY进行分组
⑵ 根据分组后的结果,查找最低工资大于5000的部门,所以是分组后加筛选条件,所以使用HAVING

步骤:
⑴ 查询各个部门的最低工资
SELECT MIN(salary), department_id
FROM employees
GROUP BY department_id;

⑵ 查询最低工资大于5000的部门
SELECT MIN(salary), department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary) > 5000;

总结

⑴ 和分组函数一起查询的可以是被分组的列
⑵ 解题步骤:
① 先分组
② 找筛选条件:如果条件所判断的是分组函数,则绝对要放在HAVING的后面;如果数据来自原始表,则放在WHERE的后面

9、连接查询

语法

SELECT 列名1, 列名2
FROM 表1, 表2
WHERE 连接条件

笛卡尔乘积

现象:最终的结果 = 表1的行数 × 表2的行数

出现的原因:没有加连接条件。
即 SELECT 列名1, 列名2
FROM 表1, 表2

需要添加连接条件来解决

连接查询的分类

⑴ 等值连接 – 非等值连接
⑵ 内连接 – 外连接
⑶ 自连接

常见错误

错误代码:1052
Column ‘???’ in field list is ambiguous
这种错误是由于指定的列不明确造成的。一般是由于查询的列,在查询的多个表中都有,即多个表含有相同的字段。
解决的方法是:使用【表名.列名】将其限制。

等值连接 – 非等值连接

等值连接


语法:
SELECT 列
FROM 表1, 表2
WHERE 连接条件(两个表的关联列相等)
【AND 分组前的条件
GROUP BY 分组的列
HAVING 分组后的条件】

特点:
⑴ 表1和表2的顺序可以调换
⑵ 两表连接需要1个条件,n表连接需要n-1个条件

⑴ 【普通的两表等值连接】
示例:查询first_name和department_name

分析:需要查找姓名和部门名,而这两个字段来自两个表,所以要将两个表连接起来,并加连接条件:两个表的字段值要相等

SELECT first_name, department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;

Tips:可以个表起个别名,方便调用表中的字段

⑵ 【添加筛选条件】
示例:查询有commission_pct的last_name和department_name

分析:
① 要查找员工名和部门名,需要将employees和departments连接起来
② 没有奖金,就是继续追加分组前的筛选条件

SELECT last_name, department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND commission_pct IS NOT NULL

⑶ 【添加分组】
示例:查询每个job_id的job_title和平均salary

分析:
① 查找工种名需要将jobs表和employees表连接起来,连接条件为job_id相等
② 其次还要查找平均工资,结果不止一个,所以要用GROUP BY进行分组

SELECT job_title, AVG(salary)
FROM employees e, jobs j
WHERE e.job_id = j.job_id
GROUP BY job_title;

非等值连接

示例:查询员工的工资级别

分析:
employees表中有salary,而salary_grades表中有grade、max_salary和min_salary三个字段。所以要使用BETWEEN…AND将这两个连接起来

SELECT grade, salary
FROM employees, salary_grades
WHERE salary BETWEEN min_salary AND max_salary;

内连接 – 外连接

语法:关键词:JOIN ON
SQL99语法(SQL1999)

分类:
内连接:表1 [INNER] JOIN 表2 ON 连接条件
INNER 可以省略
外连接:
表1 LEFT [OUTER] JOIN 表2 ON 连接条件
OUTER 可以省略
左外连接
表1 RIGHT [OUTER] JOIN 表2 ON 连接条件
OUTER 可以省略
右外连接
FULL OUTER JOIN ON
全外连接(MySQL不支持)

内连接


⑴ 示例:【普通的两表等值连接】
查询first_name和department_name

SELECT first_name, department_name
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id;

⑵ 示例:【添加筛选条件】
查询有commission_pct的last_name和department_name

SELECT last_name, department_name
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id
WHERE commission_pct IS NOT NULL;

⑶ 示例:【添加分组】
查询每个job_id的job_title和平均salary

SELECT job_title, AVG(salary)
FROM jobs j INNER JOIN employees e
ON j.job_id = e.job_id
GROUP BY job_title;

左外连接


特点:
① 左外连接,表1 LEFT JOIN 表2 ON 连接条件
表1就是主表,表2就是从表
查询的结果集是:主表中所有的记录,以及:从表中和主表匹配的记录,如果从表有和主表不匹配的记录,则用NULL填充

    即  主表某列的记录:  1 2 3 4
        从表某列的记录:  1 2
     注:某列为主从表相同的字段

     结果集:
           主表        从表
             1           1
             2           2
             3         NULL
             4         NULL

③ 一般用于查询主表中有,而从表中没有的数据
④ 左外连接和右外连接互换主从表的顺序,并更换LEFT | RIGHT 关键字,可以达到相同的效果

Tips:在解题前先想清楚,哪个表的字段要全部显示【主表】,哪个表的字段中含有NULL值【从表】。

  【一般是】
     SELECT 主表字段, 从表.主从相同字段
     FROM 主表 LEFT OUTER JOIN 从表
     ON 主表.主从相同字段 = 从表.主从相同字段
     WHERE 从表.主从相同字段 IS NULL | 从表.主从相同字段 IS NOT NULL;

⑴ 示例:显示哪个部门中没有员工
分析:
显示没有员工的部门,即departments表中的department_id的数量要比employees表中的department_id的数量多。所以departments表当主表,而employees表当从表。

① 首先显示出主表中所有的department_name
SELECT e.department_id, department_name
FROM departments d LEFT OUTER JOIN employees e
ON d.department_id = e.department_id;

② 从输出的结果可以看出:e.department_id列含有NULL值,所以接下来应当判断:e.department_id有NULL值,即为没有员工的部门

SELECT e.department_id, department_name
FROM departments d LEFT OUTER JOIN employees e
ON d.department_id = e.department_id
WHERE e.department_id IS NULL;

⑵ 示例:查询哪个国家没有部门
分析:
查询哪个国家没有部门,即locations表的location_id的数量比departments表的location_id数量多。所以locations表当主表,departments当从表

SELECT country_id, d.location_id
FROM locations l LEFT OUTER JOIN departments d
ON l.location_id = d.location_id
WHERE d.location_id IS NULL;

右外连接


特点:
① 右外连接,表1 RIGHT JOIN 表2 ON 连接条件
表2就是主表,表1就是从表
查询的结果集是仍是相同的规律:
主表中所有的记录,以及:从表中和主表匹配的记录,如果从表有和主表不匹配的记录,则用NULL填充

③ 依然用于查询主表中有,而从表中没有的数据
④ 左外连接和右外连接互换主从表的顺序,并更换LEFT | RIGHT 关键字,可以达到相同的效果

注意:在解题前先想清楚,哪个表的字段要全部显示【主表】,哪个表的字段中含有NULL值【从表】。

  【一般是】
     SELECT 主表字段, 从表.主从相同字段
     FROM 从表 RIGHT OUTER JOIN 主表
     ON 主表.主从相同字段 = 从表.主从相同字段
     WHERE 从表.主从相同字段 IS NULL | 从表.主从相同字段 IS NOT NULL;

示例:显示哪个部门中没有员工
分析:将左连接中主表从表的顺序调换,再将LEFT替换为RIGHT即可

SELECT e.department_id, d.department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;

自连接

执行主查询时又用到了子查询的结果
主查询:外查询
子查询:内查询

执行顺序:子查询优先于主查询执行

注意:
⑴ 一般会将子查询放到小括号中
⑵ 子查询一般放在右侧

分类:
⑴ 单行子查询:
子查询的结果是一个值
搭配单行操作符:>, <, =, <>, >=, <=

⑵ 多行子查询:
子查询的结果是一组值
需要搭配多行操作符:ANY/ALL/IN

ANY:和子查询结果中的某一个值比较
一般搭配 > 或 < 来使用即
> ANY (子查询) 或 < ANY (子查询)

ALL:和子查询结果中所有的值比较
一般搭配 > 或 < 来使用即
> ALL (子查询) 或 < ALL (子查询)

IN:等于子查询结果中的任意一个值
IN (子查询)
类似于:IN(值1, 值2, 值3, …)

单行子查询


⑴ 示例:【子查询用在普通的字段】
查询哪位员工的工资比’Bone’的高

① 首先查找’Bone’的工资
SELECT salary
FROM employees
WHERE last_name = ‘Bone’;

② 其次查找谁的工资比①的结果要高
SELECT last_name
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name = ‘Bone’
);

⑵ 示例:【子查询用到了分组函数】
返回公司工资最少的员工的last_name,job_id和salary

① 查找公司的最低工资是多少
SELECT MIN(salary)
FROM employees;

② 查找哪位员工的工资为①中的结果
SELECT last_name, job_id, salary
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees;
);

⑶ 示例:【子查询用到了HAVING】
查询最低salary大于50号部门的最低工资的部门编号和最低工资

① 查询50号部门的最低工资
SELECT MIN(salary)
FROM employees
WHERE department_id = 50;

② 查询每个部门的最低工资
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) > (
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);

多行子查询

⑴ 示例:【返回其他部门中比job_id为’IT_PROG’部门任意一个工资低的员工的员工号、姓名、job_id 以及salary】

① 查询job_id为’IT_PROG’部门的所有工资情况
SELECT salary
FROM employees
WHERE job_id = ‘IT_PROG’;

② 再查找其他部门的工资情况,和①相比,并查找要求的字段
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ANY (
SELECT salary
FROM employees
WHERE job_id = ‘IT_PROG’;
);

⑵ 示例:【返回其它部门中比job_id为’IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id 以及salary】

① 查询job_id为’IT_PROG’部门的所有工资情况
SELECT salary
FROM employees
WHERE job_id = ‘IT_PROG’;

② 再查找其他部门的工资情况,和①相比,并查找要求的字段
SELECT employee_id, last_name, job_id,salary
FROM employees
WHERE salary < ALL (
SELECT salary
FROM employees
WHERE job_id = ‘IT_PROG’;
);

你可能感兴趣的:(MySQL)