MySQL 子查询使用方式

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 子查询使用方式相关的知识,希望对你有一定的参考价值。

阅读目录

阐述

所谓子查询,就是嵌套在其他查询中的查询。

某些情况下,当进行一个查询时,需要的条件或数据要用另外一个 select 语句的结果,这个时候,就要用到子查询。

定义:
执行顺序方面先于当前查询执行的,并且是嵌套在当前查询中的查询叫做子查询。

mysql 在处理上例的 SELECT 语句时,执行流程为:

先执行子查询,再执行父查询。
子查询应当始终放在括号内。

子查询的支持是从 4.1 版本引入的。MySQL 的早期版本不支持子查询。

子查询分类

按照返回结果的行列数分类

1 标量子查询(结果集只有一行一列)
2 列子查询(结果集只有一列多行)
3 行子查询(结果集有一行多列)
4 表子查询(结果集一般为多列多行)

按子查询出现在主查询的位置分类

select 后面:仅支持标量子查询
  from 后面:支持表子查询

where 或者 having 后面:
支持标量子查询(单行单列)、
列子查询(单列多行)、
行子查询(多列多行)

 exists后面(即相关子查询): 表子查询(多行多列)

预备数据

部门表 departments

/*部门表*/
DROP TABLE IF EXISTS `departments`;
CREATE TABLE `departments` (
  `department_id` int(4) NOT NULL AUTO_INCREMENT comment '部门id',
  `department_name` varchar(3) DEFAULT NULL comment '部门名称',
  `manager_id` int(6) DEFAULT NULL comment '管理者id',
  `location_id` int(4) DEFAULT NULL comment '部门位置id,来源于表locations中的location_id',
  PRIMARY KEY (`department_id`),
  KEY `loc_id_fk` (`location_id`)
) ENGINE=InnoDB AUTO_INCREMENT=271 comment '部门表';

INSERT INTO `departments` (
	`department_id`,
	`department_name`,
	`manager_id`,
	`location_id`
)
VALUES
	(10, 'Adm', 200, 1700),
	(20, 'Mar', 201, 1800),
	(30, 'Pur', 114, 1700),
	(40, 'Hum', 203, 2400),
	(50, 'Shi', 121, 1500),
	(60, 'IT', 103, 1400),
	(70, 'Pub', 204, 2700),
	(80, 'Sal', 145, 2500),
	(90, 'Exe', 100, 1700),
	(100, 'Fin', 108, 1700),
	(110, 'Acc', 205, 1700),
	(120, 'Tre', NULL, 1700),
	(130, 'Cor', NULL, 1700),
	(140, 'Con', NULL, 1700),
	(150, 'Sha', NULL, 1700),
	(160, 'Ben', NULL, 1700),
	(170, 'Man', NULL, 1700),
	(180, 'Con', NULL, 1700),
	(190, 'Con', NULL, 1700),
	(200, 'Ope', NULL, 1700),
	(210, 'IT ', NULL, 1700),
	(220, 'NOC', NULL, 1700),
	(230, 'IT ', NULL, 1700),
	(240, 'Gov', NULL, 1700),
	(250, 'Ret', NULL, 1700),
	(260, 'Rec', NULL, 1700),
	(270, 'Pay', NULL, 1700);

员工表 employees

/*员工表*/
DROP TABLE IF EXISTS `employees`;
CREATE TABLE `employees` (
  `employee_id` int(6) NOT NULL AUTO_INCREMENT comment '员工id',
  `first_name` varchar(20) DEFAULT NULL comment '名',
  `last_name` varchar(25) DEFAULT NULL comment '姓',
  `email` varchar(25) DEFAULT NULL comment '电子邮箱',
  `phone_number` varchar(20) DEFAULT NULL comment '手机',
  `job_id` varchar(10) DEFAULT NULL comment '职位id,来源于jobs表中的job_id',
  `salary` double(10,2) DEFAULT NULL comment '薪水',
  `commission_pct` double(4,2) DEFAULT NULL comment '佣金百分比',
  `manager_id` int(6) DEFAULT NULL comment '上级id',
  `department_id` int(4) DEFAULT NULL comment '所属部门id,来源于departments中的department_id',
  `hiredate` datetime DEFAULT NULL comment '入职日期',
  PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=207 comment '员工表';

INSERT INTO `employees` (
	`employee_id`,
	`first_name`,
	`last_name`,
	`email`,
	`phone_number`,
	`job_id`,
	`salary`,
	`commission_pct`,
	`manager_id`,
	`department_id`,
	`hiredate`
)
VALUES
	(
		100,
		'Steven',
		'K_ing',
		'SKING',
		'515.123.4567',
		'AD_PRES',
		24000.00,
		NULL,
		NULL,
		90,
		'1992-04-03 00:00:00'
	),
	(
		101,
		'Neena',
		'Kochhar',
		'NKOCHHAR',
		'515.123.4568',
		'AD_VP',
		17000.00,
		NULL,
		100,
		90,
		'1992-04-03 00:00:00'
	),
	(
		102,
		'Lex',
		'De Haan',
		'LDEHAAN',
		'515.123.4569',
		'AD_VP',
		17000.00,
		NULL,
		100,
		90,
		'1992-04-03 00:00:00'
	),
	(
		103,
		'Alexander',
		'Hunold',
		'AHUNOLD',
		'590.423.4567',
		'IT_PROG',
		9000.00,
		NULL,
		102,
		60,
		'1992-04-03 00:00:00'
	),
	(
		104,
		'Bruce',
		'Ernst',
		'BERNST',
		'590.423.4568',
		'IT_PROG',
		6000.00,
		NULL,
		103,
		60,
		'1992-04-03 00:00:00'
	),
	(
		105,
		'David',
		'Austin',
		'DAUSTIN',
		'590.423.4569',
		'IT_PROG',
		4800.00,
		NULL,
		103,
		60,
		'1998-03-03 00:00:00'
	),
	(
		106,
		'Valli',
		'Pataballa',
		'VPATABAL',
		'590.423.4560',
		'IT_PROG',
		4800.00,
		NULL,
		103,
		60,
		'1998-03-03 00:00:00'
	),
	(
		107,
		'Diana',
		'Lorentz',
		'DLORENTZ',
		'590.423.5567',
		'IT_PROG',
		4200.00,
		NULL,
		103,
		60,
		'1998-03-03 00:00:00'
	),
	(
		108,
		'Nancy',
		'Greenberg',
		'NGREENBE',
		'515.124.4569',
		'FI_MGR',
		12000.00,
		NULL,
		101,
		100,
		'1998-03-03 00:00:00'
	),
	(
		109,
		'Daniel',
		'Faviet',
		'DFAVIET',
		'515.124.4169',
		'FI_ACCOUNT',
		9000.00,
		NULL,
		108,
		100,
		'1998-03-03 00:00:00'
	),
	(
		110,
		'John',
		'Chen',
		'JCHEN',
		'515.124.4269',
		'FI_ACCOUNT',
		8200.00,
		NULL,
		108,
		100,
		'2000-09-09 00:00:00'
	),
	(
		111,
		'Ismael',
		'Sciarra',
		'ISCIARRA',
		'515.124.4369',
		'FI_ACCOUNT',
		7700.00,
		NULL,
		108,
		100,
		'2000-09-09 00:00:00'
	),
	(
		112,
		'Jose Manuel',
		'Urman',
		'JMURMAN',
		'515.124.4469',
		'FI_ACCOUNT',
		7800.00,
		NULL,
		108,
		100,
		'2000-09-09 00:00:00'
	),
	(
		113,
		'Luis',
		'Popp',
		'LPOPP',
		'515.124.4567',
		'FI_ACCOUNT',
		6900.00,
		NULL,
		108,
		100,
		'2000-09-09 00:00:00'
	),
	(
		114,
		'Den',
		'Raphaely',
		'DRAPHEAL',
		'515.127.4561',
		'PU_MAN',
		11000.00,
		NULL,
		100,
		30,
		'2000-09-09 00:00:00'
	),
	(
		115,
		'Alexander',
		'Khoo',
		'AKHOO',
		'515.127.4562',
		'PU_CLERK',
		3100.00,
		NULL,
		114,
		30,
		'2000-09-09 00:00:00'
	),
	(
		116,
		'Shelli',
		'Baida',
		'SBAIDA',
		'515.127.4563',
		'PU_CLERK',
		2900.00,
		NULL,
		114,
		30,
		'2000-09-09 00:00:00'
	),
	(
		117,
		'Sigal',
		'Tobias',
		'STOBIAS',
		'515.127.4564',
		'PU_CLERK',
		2800.00,
		NULL,
		114,
		30,
		'2000-09-09 00:00:00'
	),
	(
		118,
		'Guy',
		'Himuro',
		'GHIMURO',
		'515.127.4565',
		'PU_CLERK',
		2600.00,
		NULL,
		114,
		30,
		'2000-09-09 00:00:00'
	),
	(
		119,
		'Karen',
		'Colmenares',
		'KCOLMENA',
		'515.127.4566',
		'PU_CLERK',
		2500.00,
		NULL,
		114,
		30,
		'2000-09-09 00:00:00'
	),
	(
		120,
		'Matthew',
		'Weiss',
		'MWEISS',
		'650.123.1234',
		'ST_MAN',
		8000.00,
		NULL,
		100,
		50,
		'2004-02-06 00:00:00'
	),
	(
		121,
		'Adam',
		'Fripp',
		'AFRIPP',
		'650.123.2234',
		'ST_MAN',
		8200.00,
		NULL,
		100,
		50,
		'2004-02-06 00:00:00'
	),
	(
		122,
		'Payam',
		'Kaufling',
		'PKAUFLIN',
		'650.123.3234',
		'ST_MAN',
		7900.00,
		NULL,
		100,
		50,
		'2004-02-06 00:00:00'
	),
	(
		123,
		'Shanta',
		'Vollman',
		'SVOLLMAN',
		'650.123.4234',
		'ST_MAN',
		6500.00,
		NULL,
		100,
		50,
		'2004-02-06 00:00:00'
	),
	(
		124,
		'Kevin',
		'Mourgos',
		'KMOURGOS',
		'650.123.5234',
		'ST_MAN',
		5800.00,
		NULL,
		100,
		50,
		'2004-02-06 00:00:00'
	),
	(
		125,
		'Julia',
		'Nayer',
		'JNAYER',
		'650.124.1214',
		'ST_CLERK',
		3200.00,
		NULL,
		120,
		50,
		'2004-02-06 00:00:00'
	),
	(
		126,
		'Irene',
		'Mikkilineni',
		'IMIKKILI',
		'650.124.1224',
		'ST_CLERK',
		2700.00,
		NULL,
		120,
		50,
		'2004-02-06 00:00:00'
	),
	(
		127,
		'James',
		'Landry',
		'JLANDRY',
		'650.124.1334',
		'ST_CLERK',
		2400.00,
		NULL,
		120,
		50,
		'2004-02-06 00:00:00'
	),
	(
		128,
		'Steven',
		'Markle',
		'SMARKLE',
		'650.124.1434',
		'ST_CLERK',
		2200.00,
		NULL,
		120,
		50,
		'2004-02-06 00:00:00'
	),
	(
		129,
		'Laura',
		'Bissot',
		'LBISSOT',
		'650.124.5234',
		'ST_CLERK',
		3300.00,
		NULL,
		121,
		50,
		'2004-02-06 00:00:00'
	),
	(
		130,
		'Mozhe',
		'Atkinson',
		'MATKINSO',
		'650.124.6234',
		'ST_CLERK',
		2800.00,
		NULL,
		121,
		50,
		'2004-02-06 00:00:00'
	),
	(
		131,
		'James',
		'Marlow',
		'JAMRLOW',
		'650.124.7234',
		'ST_CLERK',
		2500.00,
		NULL,
		121,
		50,
		'2004-02-06 00:00:00'
	),
	(
		132,
		'TJ',
		'Olson',
		'TJOLSON',
		'650.124.8234',
		'ST_CLERK'<

以上是关于MySQL 子查询使用方式的主要内容,如果未能解决你的问题,请参考以下文章

mysql 标量子查询和非法子查询

MySQL随记 - 子查询

DQL-子查询

多表查询

子查询(MySQL)

数据库子查询 ---where或having后面----列子查询-多行子查询