行走在数据库上的行癫(三)

开源数据库SQL实战(三)


Author:行癫

GitHub:https://github.com/blackmed/mysql.git


目录:

●数据库查询

● 多表查询

一:数据库查询

单表查询

简单查询

通过条件查询

查询排序

限制查询记录数

使用集合函数查询

分组查询

使用正则表达式查询

测试表:company.employee5
	雇员编号	id				        int
	雇员姓名	name			    varchar(30)
	雇员性别	sex				    enum
	雇用时期	hire_date			date
	职位			post					varchar(50)
	职位描述	job_description	varchar(100)
	薪水			salary				double(15,2)
	办公室		office			    int
	部门编号	dep_id				int

mysql> CREATE TABLE company.employee5(
     id int primary key AUTO_INCREMENT not null,
     name varchar(30) not null,
     sex enum('male','female') default 'male' not null,
     hire_date date not null,
     post varchar(50) not null,
     job_description varchar(100),
     salary double(15,2) not null,
     office int,
     dep_id int
     );

mysql> insert into company.employee5(name,sex,hire_date,post,job_description,salary,office,dep_id) values 
	('jack','male','20180202','instructor','teach',5000,501,100),
	('tom','male','20180203','instructor','teach',5500,501,100),
	('robin','male','20180202','instructor','teach',8000,501,100),
	('alice','female','20180202','instructor','teach',7200,501,100),
	('','male','20180202','hr','hrcc',600,502,101),
	('harry','male','20180202','hr',NULL,6000,502,101),
	('emma','female','20180206','sale','salecc',20000,503,102),
	('christine','female','20180205','sale','salecc',2200,503,102),
    ('zhuzhu','male','20180205','sale',NULL,2200,503,102),
    ('gougou','male','20180205','sale','',2200,503,102);

mysql> select   字段名称,字段名称2    from  表名   条件
简单查询:
mysql> select * from employee5;
mysql> select name, salary, dep_id from employee5 where id <=5;

避免重复DISTINCT
    SELECT post FROM employee5;
	SELECT distinct post  FROM employee5;	
	注:不能部分使用DISTINCT,通常仅用于某一字段。
	
通过四则运算查询
    SELECT name, salary, salary*14 FROM employee5;
    SELECT name, salary, salary*14 AS Annual_salary FROM employee5;
    SELECT name, salary, salary*14 Annual_salary FROM employee5;
    
定义显示格式
   CONCAT() 函数用于连接字符串
   SELECT concat(name, 's annual salary: ', salary*14)  AS Annual_salary FROM employee5;

单条件查询       
    SELECT name,post FROM employee5 WHERE post='hr';

多条件查询
    SELECT name,salary FROM employee5 WHERE post='hr' AND salary>10000;
    select * from employee5 where salary>5000 and salary<10000  or dep_id=102;

关键字BETWEEN AND between and
	    SELECT name,salary FROM employee5 WHERE salary BETWEEN 5000 AND 15000;

	    SELECT name,salary FROM employee5  WHERE salary NOT BETWEEN 5000 AND 15000;

关键字IS NULL
	    SELECT name,job_description FROM employee5 WHERE job_description IS NULL;

	    SELECT name,job_description FROM employee5 WHERE job_description IS NOT NULL;
		
	    SELECT name,job_description FROM employee5  WHERE job_description='';
		
		NULL说明:
        1、等价于没有任何值、是未知数。
        2、NULL与0、空字符串、空格都不同,NULL没有分配存储空间。
        3、对空值做加、减、乘、除等运算操作,结果仍为空。
        4、比较时使用关键字用“is null”和“is not null”。
        5、排序时比其他数据都小(索引默认是降序排列,小→大),所以NULL值总是排在最前。

    关键字IN集合查询
	    SELECT name, salary FROM employee5 
		    WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;
	
	    SELECT name, salary FROM employee5 
		    WHERE salary IN (4000,5000,6000,9000) ;

	    SELECT name, salary FROM employee 
		    WHERE salary NOT IN (4000,5000,6000,9000) ;
		
	关键字LIKE模糊查询
	通配符’% ’:所有字符
	SELECT * FROM employee5 WHERE name LIKE 'al%';

	通配符’_’  一个字符
	SELECT * FROM employee5 WHERE name LIKE 'al___';
排序查询
        
    mysql> select china from t1 order by china;
    mysql> select china from t1 order by china desc;
    mysql> select china from t1 order by china desc limit 3;  控制显示前3行。
    mysql> select china from t1 order by china desc limit 1,3; 从序号1开始显示三行的内容。

    注:
    ascending    美音 /ə'sɛndɪŋ/   升序
    descending  美音 /dɪ'sɛndɪŋ/  降序

    按多列排序:
        入职时间相同的人薪水不同
	    SELECT * FROM employee5 ORDER BY hire_date DESC,salary ASC; 
    	限制查询的记录数
	    SELECT * FROM employee5 ORDER BY salary DESC LIMIT 5;	    //默认初始位置为0 

	    SELECT * FROM employee5 ORDER BY salary DESC LIMIT 0,5;

	    SELECT * FROM employee5 ORDER BY salary DESC LIMIT 3,5;	   //从第4条开始,共显示5条

使用集合函数查询
count  可以查看共有多少条记录
select count(*)  from employee5;
select count( name) from employee5;
select max(salary) from employee5;       //部门薪资最高
select min(salary) from employee5;
select avg(salary) from employee5;

sale这个部门的总工资:
select concat("Total Department Wages:",sum(salary)) from employee5 where post='sale';
打印薪水最高的这个人的详细信息:
select * from employee5 where salary = (select max(salary) from employee5);

分组查询:
	GROUP BY和GROUP_CONCAT()函数一起使用
    部门ID相同,就把名字拼到一起:
	SELECT dep_id,GROUP_CONCAT(name) FROM employee5 GROUP BY dep_id;
	SELECT dep_id,GROUP_CONCAT(name) as emp_members FROM employee5 GROUP BY dep_id; 
	GROUP BY和集合函数一起使用
	部门最高薪资
	SELECT post,max(salary) FROM employee5 GROUP BY post;
+------------+-------------+
| post       | max(salary) |
+------------+-------------+
| hr         |     6000.00 |
| instructor |     8000.00 |
| sale       |    20000.00 |
+------------+-------------+
3 rows in set (0.07 sec)

正则查询
    SELECT * FROM employee5 WHERE name REGEXP '^ali';
    SELECT * FROM employee5 WHERE name REGEXP 'yun$';

小结:对字符串匹配的方式
WHERE name = 'tom';
WHERE name LIKE 'to%';  _ %

二:多表查询

​ 左右内链接

​ 多表连接查询

​ 复合条件连接查询

一、准备两张测试表
表company.employee6

mysql> create table employee6( 
emp_id int auto_increment primary key not null, 
emp_name varchar(50), 
age int, 
dept_id int);
mysql> desc employee6;
mysql> insert into employee6(emp_name,age,dept_id) values
('',19,200),
('tom',26,201),
('jack',30,201),
('alice',24,202),
('robin',40,200),
('xingdian',16,200),
('natasha',28,204);
mysql> select * from employee6;

表company.department6

mysql> create table department6(
dept_id int,
dept_name varchar(100)
);
mysql> desc department6;
mysql> insert into department6 values
(200,'hr'),
(201,'it'),
(202,'sale'),
(203,'fd');
mysql> select * from department6;
注:
Financial department:财务部门 fd

二、多表的连接查询
交叉连接:     生成笛卡尔积,它不使用任何匹配条件
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合

内连接:		只连接匹配的行
外连接
    左连接:	会显示左边表内所有的值,不论在右边表内匹不匹配
    右连接:	会显示右边表内所有的值,不论在左边表内匹不匹配

全外连接: 	包含左、右两个表的全部行

=================交叉连接=======================
 >select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6;

=================内连接=======================
只找出有部门的员工 (部门表中没有natasha所在的部门)
>select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6 where employee6.dept_id=department6.dept_id;

>select employee6.emp_name,department6.dept_name from employee6 inner join department6 on employee6.dept_id=department6.dept_id;

外连接语法:
SELECT 字段列表
	    FROM 表1 LEFT|RIGHT JOIN 表2
	    ON 表1.字段 = 表2.字段;

先用谁谁就是左。
=================外连接(左连接 left join)=======================
mysql> select emp_id,emp_name,dept_name from  employee6 left join department6 on employee6.dept_id = department6.dept_id;
找出所有员工及所属的部门,包括没有部门的员工
=================外连接(右连接right join)=======================
mysql> select emp_id,emp_name,dept_name from  employee6 right join department6 on employee6.dept_id = department6.dept_id;
找出所有部门包含的员工,包括空部门
=================全外连接=======================
mysql> select * from employee6 full join department6;
+--------+----------+---------+---------+-----------+
| emp_id | emp_name | dept_id | dept_id | dept_name |
+--------+----------+---------+---------+-----------+
|      1 |   |     200 |     200 | hr        |
|      1 |   |     200 |     201 | it        |
|      1 |   |     200 |     202 | sale      |
|      1 |   |     200 |     203 | fd        |
|      2 | tom      |     201 |     200 | hr        |
|      2 | tom      |     201 |     201 | it        |
|      2 | tom      |     201 |     202 | sale      |
|      2 | tom      |     201 |     203 | fd        |
|      3 | jack     |     201 |     200 | hr        |
|      3 | jack     |     201 |     201 | it        |
|      3 | jack     |     201 |     202 | sale      |
|      3 | jack     |     201 |     203 | fd        |
|      4 | alice    |     202 |     200 | hr        |
|      4 | alice    |     202 |     201 | it        |
|      4 | alice    |     202 |     202 | sale      |
|      4 | alice    |     202 |     203 | fd        |
|      5 | robin    |     200 |     200 | hr        |
|      5 | robin    |     200 |     201 | it        |
|      5 | robin    |     200 |     202 | sale      |
|      5 | robin    |     200 |     203 | fd        |
|      6 | natasha  |     204 |     200 | hr        |
|      6 | natasha  |     204 |     201 | it        |
|      6 | natasha  |     204 |     202 | sale      |
|      6 | natasha  |     204 |     203 | fd        |
+--------+----------+---------+---------+-----------+
24 rows in set (0.00 sec)

三、复合条件连接查询
示例1:以内连接的方式查询employee6和department6表,并且employee6表中的age字段值必须大于25
找出公司所有部门中年龄大于25岁的员工
示例2:以内连接的方式查询employee6和department6表,并且以age字段的升序方式显示
四、子查询
子查询是将一个查询语句嵌套在另一个查询语句中。
内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN等关键字
还可以包含比较运算符:=!=><等
1. 带IN关键字的子查询
查询employee表,但dept_id必须在department表中出现过
2. 带比较运算符的子查询
=!=>>=<<=<>
查询年龄大于等于25岁员工所在部门(查询老龄化的部门)
发布了45 篇原创文章 · 获赞 26 · 访问量 4253

猜你喜欢

转载自blog.csdn.net/zy_xingdian/article/details/103514995