MySQL数据查询

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

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

  【一般是】
     SELECT 主表字段, 从表.主从相同字段
     FROM 主表 LEFT OUTER JOIN 从表
     ON 主表.主从相同字段 = 从表.主从相同字段
     WHERE 从表.主从相同字段 IS NULL | 从表.主从相同字段 IS NOT NULL;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

⑴ 示例:显示哪个部门中没有员工 
分析: 
显示没有员工的部门,即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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

示例:显示哪个部门中没有员工 
分析:将左连接中主表从表的顺序调换,再将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’; 
);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值