mysql

web到服务器到数据库。
数据库中MySQL44.3%的用户量。
MYSQL是开源的,在IT行业中无人不知了。
为什么使用数据库来存储数据?
数组 集合存在内存中,不可以永久存储。
文件可以永久存储,数据太多查询麻烦。
数据库可以持久化数据,有好的管理系统容易查询。
DB?
database:数据库中的数据有组织,有规范。
DBMS?
Database Management System:数据库管理系统,创建和操作数据库中的空间。学的是数据库管理系统,简称称了数据库。
典型的数据库管理系统就有MySql,Oracle(要钱),DB2(适合处理海量的数据),SqlServer(微软公司,只能装在Windows系统中).
Sql?
数据库管理系统操作指令。特点:1.几乎所有的数据库操作系统都支持SQL2.简单易学。3.灵活使用可产生很复杂的效果。
数据库如何存储数据?
先将数据存储到表里,在把表放在库里。

数据库中有很多的表,每个表都有一个名字不可以重复。

表是由列组成,称为字段。

MySQL安装使用。
MySQL属于MySQLAB公司,总部在瑞典。老总Monty,天才程序员,50多岁还在编程。08年被sun公司收购,09年被Orecle公司收购。
优点:开源,执行快,轻量级。
DBMS分为两大类:架构不同。
两个版本,社区版,企业版(收费)。
安装服务端。
my.ini为配置文件。关心服务端的配置。
MySQL的启动和停止。
第一种:右击计算机--管理--服务  第二种:打开管理员的dos窗口net start+数据库名,net stop+数据库明。

MySQL的登陆和退出。第一种:在MySQL Command Line Client 的类似于dos的窗口中直接输入密码就可以了。退出就输入exit或Ctrl+c这种方式只适用root用户
第二种:在管理员dos中输入mysql -hlocalhost -P3306 -uroot -p 然后回车输入密码,退出就是输入exit或Ctrl+c。

MySQL的常见命令:show databases;(查看有哪些数据库)use +库名+回车+show tables+回车(查看库的内容)show tables from+库名+回车(查看库的内容)
select database();(查看目前你在使用哪个库)
练习;
net stop MySQL;//停止数据库运行
net start MySQL;//启动数据库运行
mysql -hlocalhost -uroot -p1023;//打开数据库
show databases;//查看数据库有哪些库
use test;//使用test库
create table stuinfo(id int,name varchar(20));//在test库中创建一张名叫stuinfo的表
show tables;//查看test数据库中有哪些表
desc stuinfo;//查看stuinfo表的结构
insert into stuinfo(id,name) values(1,"john");//向表stuinfo中插入数据
insert into stuinfo(id,name) values(2,"rose");//向表stuinfo中插入数据
select*from stuinfo;//从表stuinfo中查找数据
update stuinfo set name=“lilei”where id=1;//将表stuinfo中id为1的name改为lilei;
select*from stuinfo;//从表stuinfo中查找数据。
delete from stuinfo where id=1;//删除表stuinfo表中id为1 的数据。
select*from stuinfo ;//查看表stuinfo中的数据。
select version();//查看数据库管理系统的版本。
exit//推出数据库管理系统客户端。
mysql --version//在dos窗口下查看数据库管理系统的版本。dos命令不用加分号。
mysql -V//在dos窗口下查看数据库管理系统的版本。dos命令不用加分号。

myaql语法不区分大小写;建议关键字大写,表名列名小写。
每条命令用分号结尾;
每条命令根据需要不打分号可以回车换行;
注释是用符号:单行注释:#注释文字    或-- 注释文字
		多行注释:/* 注释文字 */
数据库管理系统的图形化界面我们使用SQLyog客户端
在图形界面中敲进命令 然后选中命令 点执行按钮或按f9快捷键执行
工具--首选项--调节字体
 年终奖2个点是月薪的二倍。  
将人事部门用数字1代替,被称为分类存储。

基础查询
select 查询的东西(表中的字段,常量值,表达式,函数)
from 从哪个表里查东西;
查询到的结果是临时性的。
练习:
USE myemployees;
SELECT last_name FROM `employees`;
SELECT last_name,salary,email FROM employees;
SELECT * FROM employees;
SELECT 100;#查询常量可不用加表
SELECT "john";#查询字符常量
SELECT 100+20;#查询100+2的结果
SELECT VERSION();#查询该函数的返回值
#给查询的字段起别名
SELECT 100 AS 结果;
SELECT last_name AS,first_name ASFROM employees;#便于理解#使用了as
SELECT last_name AS,first_name ASFROM employees;#便于理解#将as换成了空格
#去重
#查询员工表中涉及到的部门编号
SELECT department_id FROM employees;#未去重
SELECT DISTINCT department_id FROM employees;#去重后
#加号的作用
#将姓和名字段连接成一个字段显示为姓名
#java中的加号的作用:数值运算符,字符串的拼接功能
#mysql中只有数值运算符的作用
SELECT 100+100;
SELECT "123"+90;#mysql会试图将字符转换成数字,转换成功就运算
SELECT "john"+90;#mysql将字符转换成数字失败就将字符当为0去运算
SELECT NULL+10;#有null结果为null
SELECT CONCAT(last_name,first_name) AS 姓名 FROM employees;
SELECT CONCAT(first_name,last_name,job_id,commission_pct) AS out_put FROM employees;#因为commission_pact的值为null所以拼接后查询到的结果为null
SELECT IFNULL(commission_pct,0) AS 奖金率,commission_pct FROM employees;#函数ifnull()的意思是如果commission_pct的值为null值时就将null值换成0显示。
SELECT CONCAT(first_name,last_name,job_id,IFNULL(commission_pct,0)) AS out_put FROM employees;
#条件查询
#select 查询列表 from 表 where 筛选条件;#执行顺序为表——筛选条件——查询列表
#条件运算符:> < = <>(不等于) >= <=
#逻辑运算符:&& || !and or not(推荐使用英文)
#模糊查询:like    between and      in       is null
#查询员工工资大于12000的员工信息
SELECT * FROM employees WHERE salary>12000;
#查询部门编号不等于90号的员工名和部门编号
SELECT last_name,department_id FROM employees WHERE department_id<>90;
#查询工资再10000到20000之间的员工名,工资,奖金
SELECT last_name,salary,commission_pct FROM employees WHERE salary>=10000 AND salary<=20000;
#查询部门编号不是再90到110之间或工资高于15000的员工信息
SELECT * FROM employees WHERE department_id<90 OR department_id>110 OR salary>15000;
SELECT * FROM employees WHERE NOT(department_id>=90 AND department_id<=110) OR salary>15000;
#查询员工名中包含字符a的员工信息
SELECT * FROM employees WHERE last_name LIKE "%a%";#%代表了通配符。意思是任意多个字符,"_"代表了单个任意的字符
#查询员工名中第三个字符为n第五个字符为l的员工名和工资
SELECT last_name,salary FROM employees WHERE last_name LIKE "__n_l%";
#查询员工名中第二个字符为_的员工名
SELECT last_name FROM employees WHERE last_name LIKE "_\_%";
SELECT last_name FROM employees WHERE last_name LIKE "_$_%" ESCAPE "$";#$可换成任意一个字符,escape的意思是将$定义为转义字符。
#查询员工编号再100到120之间的员工信息
SELECT * FROM employees WHERE employee_id >=100 AND employee_id<=120;
SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120;
#使用between and是闭区间。100和120不可以颠倒顺序。
#查询员工工种编号是IT_PROG,AD_VP,AD_PRES中的一个的员工名和工种编号
SELECT last_name,job_id FROM employees WHERE job_id="IT_PROG" OR job_id ="AD_VP" OR job_id="AD_PRES";
SELECT job_id FROM employees WHERE job_id LIKE "I%";
#in里面不支持通配符。
#查询没有奖金的员工名和奖金率
SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NULL;
#查询没有奖金的员工名和奖金率
SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NOT NULL;#=和<>不能用于判断null值
#安全等于<=>也可以用来判断null值,也可以用来判断数值,意思就是等于。
SELECT last_name,commission_pct FROM employees WHERE commission_pct <=> NULL;
#查询员工号为176的员工的姓名和部门号和年薪。
SELECT last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) AS 年薪 FROM employees;#注意使用ifnull
#查询employees表中,job_id不为“IT”或者工资为12000的员工信息
SELECT * FROM employees WHERE job_id<>"IT" OR salary=12000;#is只能用来判断null值。
#试问:select * from employees;和select * from employees where commission_pct like "%%" and last_name like "%%";结果是否一样。
#答:如果判断的字段有null值那么结果就会不一样。
#试问:select * from employees;和select * from employees where commission_pct like "%%" or last_name like "%%";结果是否一样。
#答:如果判断的字段有null值那么结果就会不一样。
#复习
#数据库的好处:持久化数据,结构化查询
#DB:数据库
#DBMS:数据库管理系统或叫数据库产品,用来创建和管理数据库
#SQL:结构化查询语言,用于和数据库进行通讯的语言,几乎所有数据库都通用、
#数据库存放的特点:数据放在表里,表放在库里
#一个库里可有多张表,表的名字不可重复
#常见的数据库管理系统mysql,oricle,db2
#MySQL的背景:前生是瑞典AB公司的,08年有sun收购,09年由Oracle收购
#MySQL的体积小,开源,免费,成本低,性能好,可移植性好
#MySQL是c/s架构软件,一般安装服务端
#MySQL服务的启动和停止:net start 服务名,net stop 服务名,计算机--右击--管理--服务
#MySQL的登陆和退出:MySQL -hlocalhost -p3306 -uroot -p1023,exit或ctrl加c
#select 查询列表 from 表名
#查询的结果是虚拟的表
#select 字段名 from 表名
#select * from 表名
SELECT 100 FROM employees;#查出来的结果是,employees表中有多少行就会显示多少个100;
#select 后面的字符型和日期型的常量值必须用引号引起来。
#select后面的函数必须返回值。
#起别名的两种方式为用as或用空格,少的话可以使用空格。
#去重就是在字段前加distinct
#select distinct a,b from 表名;不可以这么写
#+号的作用就是做加法运算,数值加数值就直接运算,数值加字符先看字符与数值兼容吗,不兼容就将字符当成0
#null+值,结果为null
#ifnull();判断字段是否为null,如果为null那么就返回给定值。 如果不给返回值那么就返回0或1
#select 查询列表 from 表名 where 筛选条件
#筛选条件的分类:简单条件运算符:> < = <> != <=> >= <=,逻辑运算符:&& || !and or not 模糊查询:like between and in is null
#like也可以用来判断数值型
SELECT * FROM employees WHERE department_id LIKE "1__";
#常见的通配符:%和_
#in 和between and是用来提高可读性的
#is是专门用来判断null值的
#<=>可以用来判断null值和数值

#查询排序
#select 查询列表 from 表 where 筛选条件 order by 排序列表 asc/desc
#查询员工信息,要求按工资从高到低
SELECT * FROM employees ORDER BY salary ASC;升序
SELECT * FROM employees ORDER BY salary DESC;降序
#查询部门编号>=90的员工信息,按入职时间的先后进行排序
SELECT * FROM employees WHERE department_id>=90 ORDER BY hiredate ;
#按表达式排序
#按年薪的高低显示员工的信息和年薪,按年薪排序
SELECT * ,salary*12*(1+IFNULL(commission_pct,0)) AS 年薪 FROM employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
SELECT * ,salary*12*(1+IFNULL(commission_pct,0)) AS 年薪 FROM employees ORDER BY 年薪 DESC;
#按姓名的长度显示员工的姓名和工资
SELECT LENGTH(last_name) AS 姓名长度,last_name,salary FROM employees ORDER BY LENGTH(last_name) DESC;
#查询员工信息,要求先按工资降序排序,再按员工编号升序排序。
SELECT * FROM employees ORDER BY salary DESC,employee_id ASC;
#执行顺序:order by 一般放在查询语句的最后面,limit字句是放在order by的最后
#选择工资不在8000到17000的员工的姓名和工资,按工资降序。
SELECT last_name,salary FROM employees WHERE salary NOT BETWEEN 8000 AND 17000 ORDER BY salary DESC;
#查询邮箱中包含e的员工信息,并先按邮箱的字节数降序排序,再按部门号升序排序。
SELECT * FROM employees WHERE email LIKE "%e%" ORDER BY LENGTH(email) DESC,department_id ASC;  

#  常见函数
#函数类似于Java中的方法,将一组语句封装在反法体中,对外暴露函数名,隐藏了细节,提高了代码的重用性。
#调用函数的方法:select 函数名(实参列表) from 表;最后就会显示函数的返回值。
#注意点:函数的名字,函数的功能
#函数的分类:单行函数,分组函数
#单行函数是做处理的
#分组函数是做统计的,又称统计函数
#字符函数
#length()
SELECT LENGTH("john");#获取长度
SELECT LENGTH("张三丰haah");获取字符串的字节数
SHOW VARIABLES LIKE "%char%";#显示系统使用的字符集(为utf-8);utf-8下一个汉字占三个字节,一个英文占一个字节。
#concat()字符拼接;
SELECT CONCAT(last_name,"_",first_name) AS 姓名 FROM employees;
SELECT UPPER("john");#将字符变大写
SELECT LOWER("DKSAFH")#将小写变大写。
#将姓变大写名变小写起别名为姓名然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name)) AS 姓名 FROM employees;#函数可以嵌套调用
#substr,substring等价,截取字符串,有四个重载方法
SELECT SUBSTR('李莫愁爱上了陆展元',7) AS out_put;#注意sql语言的索引是从1开始的,不是从0开始,截取了陆展元
SELECT SUBSTR("李莫愁爱上了陆展元",1,3) AS out_put;#截取了李莫愁
#将姓名中首字符大写,其他字符小写然后用_拼接
SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),SUBSTR(last_name,2),'_',first_name) FROM employees;
#instr()
#select instr('杨不悔爱上了殷六侠','殷六侠') as output ;#返回字串在大串中第一次出现的索引,如果找不到就返回0
#trim()去前后空格
SELECT TRIM('  张翠山  ') AS output;
SELECT TRIM('a' FROM "aaaa张aaa求aaaaaaa");#去字符串中的a
#lpad()
SELECT LPAD('殷素素',10,'*') AS output;#对字符串进行填充使总长度为10个字符,注意不是10个字节
SELECT LPAD('殷素素',2,'*') AS output;#显示的是殷素
#rpad() 右填补,pad的英文意思就是填补的意思
SELECT RPAD('殷素素',12,'ab') AS ouput;
#replace() 替换
SELECT REPLACE('张无忌爱上了周芷若','周芷若','赵敏') AS output;
SELECT REPLACE('张无忌爱上了周芷若,周芷若,周芷若','周芷若','赵敏') AS output;#里面的周芷若都会被换成赵敏
#数学函数
#round 取最近整数
SELECT ROUND(1.65);#结果为2
SELECT ROUND(-1.55);#结果为-2
SELECT ROUND(1.567,2);#保留两位有效数字
#ceil向数轴正方向取整
SELECT CEIL(1.02);
#floor 向数轴负方向取整
SELECT FLOOR(1.02);
#truncate 截断
SELECT TRUNCATE(1.69999,1);
#mod()#取余
SELECT MOD(-10,3);#先取绝对值进行取余,取余结果正负号看-10,-10为负数,所以取余结果为负
SELECT 10%3;  
#日期函数
#now()返回当前系统日期+时间
SELECT NOW();
#curdate() 返回当前系统的日期
#curtime() 返回当前系统的时间
SELECT YEAR(NOW());#返回当前系统日期的年
SELECT YEAR('1998-1-1');#返回给定日期的年
SELECT YEAR(hiredate) FROM employees;#返回表中字段hiredate中的年
SELECT MONTH(NOW());#返回当前系统日期的月
SELECT MONTHNAME(NOW());#返回当前系统日期的月,以英文显示
#str_to_date() 将与日期兼容的字符串,转换成日期;
#%Y4位的年份 %y2位的年份 %m月份(01,02....,11,12) %c(1,2,...,11,12) %d日(01,02,...,30,31) %H小时(24小时制) %h小时(12小时制)%i分钟(00,01,...,59) %s秒(00,01,...,59)
SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS 日期;
SELECT STR_TO_DATE('1998-3-2','%Y-%m-%d') AS 日期;
#在MySQL中怎么好像%m和%c是等价的
#在MySQL提示窗中出现的syntax的意思是句法manual是手册说明的意思
#查询入职日期位1992-4-3的员工信息
SELECT * FROM employees WHERE hiredate='1992-4-3';
#从web中获得的日期数据为字符,需要转
SELECT * FROM employees WHERE hiredate=STR_TO_DATE('4-3 1992','%c-%d %Y');
#date_format将日期转换为字符
SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日') AS 日期;
#查询有奖金的员工名和入职日期(xx月/xx日 xx年)
SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %Y年')FROM employees;
#version()
SELECT VERSION();
SELECT DATABASE();#查看当前使用库
SELECT USER();#查看当前使用者
#if()
SELECT IF(10<5,'是的','不是');
SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金,呵呵','有奖金,嘻嘻') AS 备注 FROM employees;
#case()
#case 要判断的字段或表达式 when 常量1 then 要显示的值或语句 when 常量1 then 要显示的值或语句 else 要显示的值或语句 end
#查询员工的工资,要求部门号=30,显示的工资为1.1倍 部门号=40,显示的工资为1.2倍 部门号=50,显示的工资为1.3倍 其他部门,显示的工资为原工资
SELECT salary AS 原始工资,department_id,CASE department_id WHEN 30 THEN salary*1.1 WHEN 40 THEN salary*1.2 WHEN 50 THEN salary*1.3 ELSE salary END AS 新工资 FROM employees;
#case的多重
#case wen 条件 then 要显示的值或语句 ... else 要显示的值 end
#查询员工的工资的情况
#如果工资>20000,显示为级别A
#如果工资>15000,显示为级别B
#如果工资>10000,显示为级别C
#否则,显示为级别D
SELECT salary,CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'c'
ELSE 'D'
END AS 工资级别
FROM employees;
#分组函数
SELECT SUM(salary) FROM employees;#对salary进行求和
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT COUNT(salary) FROM employees;
SELECT SUM(salary) AS,AVG(salary) AS 平均 FROM employees;
#分组函数参数支持哪些类型?
SELECT SUM(last_name) FROM employees;#虽未报错但是结果无意义
#sum avg 处理数值型
SELECT MAX(last_name),MIN(last_name) FROM employees;#这个是好使的
SELECT MAX(hiredate),MIN(hiredate) FROM employees;#这个是好使的
SELECT COUNT(commission_pct) FROM employees;#中计数只计数不为空的
SELECT SUM(commission_pct),AVG(commission_pct) FROM employees;#求和也是忽略null值,求平均也是忽略null值的
#所有的分组函数都忽略null值的
#和distinct结合使用
SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;
SELECT COUNT(DISTINCT salary),COUNT(salary) FROM employees;
#count的单独介绍
#count
SELECT COUNT(salary) FROM employees;
SELECT COUNT(*) FROM employees;#统计出表中的行数
SELECT COUNT(1) FROM employees;#统计出表中的行数
SELECT COUNT(2) FROM employees;#统计出表中的行数
SELECT COUNT('张权民') FROM employees;#统计出表中的行数
#存储引擎不同上面的方法谁效率高不一定,用count(*)比较多
#和分组函数一同查询的字段有限制
SELECT AVG(salary),first_name FROM employees;#结果无意义
#datediff()
SELECT DATEDIFF('2017-10-1','2017-9-8');#前面日期减去后面日期得出天数,可以查你活了多少天
SELECT DATEDIFF('2020-4-11','1996-12-3');
SELECT DATEDIFF('2020-4-11','1996-10-23');
SELECT DATEDIFF('2020-4-11','2020-4-10');
#分组查询
#查询每个部门的平均工资
SELECT AVG(salary),department_id FROM employees GROUP BY department_id;
#查询每个工种的最高工资
SELECT MAX(salary),job_id FROM employees GROUP BY job_id;
#查询每个位置上的部门个数
SELECT COUNT(*),location_id FROM departments GROUP BY location_id; 
#查询部门编号,邮箱中包含a字符的,每个部门的平均工资
SELECT department_id,AVG(salary) FROM employees WHERE email LIKE '%a%' GROUP BY department_id;
#查询有奖金的每个领导手下的最高员工工资
SELECT MAX(salary),manager_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id;#这个工资到底是零领导的工资还是员工的工资
#添加复杂筛选条件
#查询哪个部门的员工个数>2
#查询每个部门的员工个数
#根据上面的结果查询哪个部门的员工个数>2
SELECT COUNT(*),department_id FROM employees GROUP BY department_id;
SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*)>2;
#查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
#先查询每个工种有奖金的员工的最高工资
#再筛选最高工资大于12000的
SELECT MAX(salary),job_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id HAVING MAX(salary)>12000;
#查询领导编号>102的每个领导手下的最低员工工资>5000的领导编号是哪个,以及其最低工资。
#先查询每个领导手下的员工固定最低工资
SELECT manager_id,MIN(salary) FROM employees WHERE manager_id>102 GROUP BY manager_id HAVING MIN(salary)>5000;
#分组查询:分组前筛选(原始表),分组后筛选(使用分组后的结果集);它们筛选的数据源不同
#分组函数做条件肯定是放在having里面
#能用分组前筛选的就优先使用分组前筛选
#按表达式或含函数分组
#按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
SELECT COUNT(*) AS 员工个数,LENGTH(CONCAT(last_name,first_name)) AS 员工姓名长度 FROM employees GROUP BY 员工姓名长度 HAVING COUNT(*)>5;
#group by 和 having 后面是支持别名的,where后面不支持别名,这也就是在Mysql中这样,其他数据库管理系统中是不支持别名的。
SELECT salary,last_name ASFROM employees WHERELIKE "%k%";#此句会报错
SELECT salary,last_name ASFROM employees WHERE last_name LIKE '%k%';#此句不会报错
SELECT salary,last_name ASFROM employees WHERE last_name LIKE "%k%";#mysql中单引号和双引号是等价的
#按多个字段分组
#查询每个部门每个工种的员工的平均工资
SELECT AVG(salary),department_id,job_id FROM employees GROUP BY job_id,department_id;#group by 后面的条件是可以颠倒的
#查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
#下面这条查询语句是添油加醋后的
SELECT AVG(salary),department_id,job_id FROM employees WHERE department_id IS NOT NULL GROUP BY job_id,department_id HAVING AVG(salary)>10000 ORDER BY AVG(salary) DESC;
#总结
#group by子句可以支持多字段,没有顺序要求

#连接查询又叫多表连接
#查询的字段来自于多个表
SELECT NAME,boyName FROM beauty,boys;#所得数据与事实不符,得到的结果是两表行数的乘积,又称笛卡尔乘积。
#需要有效的连接条件
SELECT NAME,boyName FROM boys,beauty WHERE beauty.boyfriend_id=boys.id;
#连接查询有分类:sql92(仅支持内连接)和sql99标准  内连接,外连接,交叉连接
#等值连接
#查询女生名和对应男生名
SELECT NAME,boyName FROM boys,beauty WHERE boys.id=beauty.boyfriend_id;
#查询员工名对应的部门名
SELECT last_name,department_name FROM employees,departments WHERE employees.department_id=departments.department_id;
#查询员工名,工种号,工种名
SELECT last_name,employees.job_id,job_title FROM employees,jobs WHERE employees.job_id=jobs.job_id;#job_id使用了表名去限定,也可以为表起别名
SELECT last_name,e.job_id,job_title FROM employees AS e,jobs AS j WHERE employees.job_id=jobs.job_id;#会报错,为表起了别称where后面得用表的别称,好像和where后面不可以用字段名的别称不同
SELECT last_name,e.job_id,job_title FROM employees AS e,jobs AS j WHERE e.job_id=j.job_id;#where后面用了表的别称不会报错,但是不用表的别称会报错
#为表起了别名就不可以用表名去限定了,必须使用别名
#表连接条件的顺序可以颠倒
#表连接:可以加筛选吗?
#查询有奖金的员工名,部门名
SELECT last_name,department_name,commission_pct  FROM employees e,departments d WHERE e.department_id=d.department_id AND e.commission_pct IS NOT NULL;#where后面只给一个判断值,如果还有判断值,使用and加判断值
#查询城市名中第二个字符为o的部门名和城市名
SELECT department_name,city FROM departments d,locations l WHERE d.location_id=l.location_id AND city LIKE '_o%';
#查询每个城市的部门个数
SELECT COUNT(*) AS 个数,city FROM  departments d,locations  l WHERE d.location_id=l.location_id GROUP BY city;
#查询有奖金的每个部门名和部门的领导编号和该部门的最低工资
SELECT commission_pct,d.department_name,d.manager_id,MIN(salary) FROM employees e,departments d WHERE e.department_id=d.department_id  AND commission_pct IS NOT NULL GROUP BY e.department_id,d.department_id;
SELECT department_name,d.manager_id,MIN(salary) FROM departments d,employees e WHERE d.department_id=e.department_id AND commission_pct IS NOT NULL GROUP BY department_name,d.manager_id;
#加排序
#查询每个工种的工种名和员工的个数,并且按员工数降序
SELECT job_title,COUNT(*) FROM employees e,jobs j WHERE e.job_id=j.job_id GROUP BY job_title ORDER BY COUNT(*) DESC;
#是否可以实现三表连接
#查询员工名,部门名,所在的城市;
SELECT last_name,department_name,city FROM employees e,departments d,locations l WHERE e.department_id=d.department_id AND d.location_id=l.location_id;

#非等值连接
#查询员工的工资和工资级别
SELECT salary,grade_level FROM employees e,job_grades g WHERE e.salary BETWEEN g.lowest_sal AND g.highest_sal;
#自连接(自己连接自己)
#查询员工名和上级的名称
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name FROM employees e,employees m WHERE e.manager_id=m.manager_id;
#复习
#select from where order by 
#asc升序 不写默认为升序
#desc降序
#排序列表 :单,多字段 函数 表达式 别名
#函数:提高代码重用性,隐藏细节,提高效率
#select+函数名就可以调用函数了
#substr() concat() instr() upper() lower() replace() length() trim() lpad() rpad()
#ceil() round() mod() floor() trancate() rand()(放回0到1之间的数) 
#now() year() month() day() date_format() curdate() str_to_date() curtime() hour() minute() second() datediff() monthname()
#version() database() user() password()(返回该字符的加密形式) MD5()(返回该字符的加密形式)
#流程控制函数 if(1,2,3):1成立返回2,1不成立,放回3
#case 情况1 when 常量 then else end
#case when 条件1 then else end
#max() min() sum() avg() count() 忽略null值,可搭配distinct使用来去重
#count(字段),count(*)
#查询每个部门的员工个数
SELECT COUNT(*),department_id FROM employees GROUP BY department_id;  
#count(0);
#select  from  where group by having order by
#分组前筛选:where  分组后筛选:having 分组前和分组后的区别不就是原来表里由还是没有的区别嘛;
#多表连接,用到了多个表的字段
#连接由sql92(等值 非等值 自连接) 和sql99(内外连接,交叉连接)
#等值连接是使用两表的交集部分
#sql99
#select from 表 join 表2  连接类型(inner left right full cross )on 连接条件 where 筛选条件 group by having order by
#内联接
#select 字段 from 表1 inner join 表2 on 连接条件
#查询员工名,部门名
SELECT last_name,department_name FROM employees e INNER JOIN departments d ON e.department_id=d.department_id;
#查询名字中包含e的员工名和工种名
SELECT last_name,job_title FROM employees e INNER JOIN jobs j ON e.job_id=j.job_id WHERE e.last_name LIKE '%e%';
#查询部门个数>3的城市名和部门个数
SELECT city,COUNT(*) AS 部门个数 FROM departments d INNER JOIN locations l ON d.location_id=l.location_id GROUP BY city HAVING COUNT(*)>3;
#查询哪个部门个的员工个数>3的部门名和员工个数,并按个数降序;
SELECT COUNT(*),department_name FROM employees e INNER JOIN departments d ON e.department_id=d.department_id GROUP BY department_name HAVING COUNT(*)>3 ORDER BY COUNT(*) DESC;
#查询员工名,部门名,工种名,并按部门名降序
SELECT last_name,department_name,job_title FROM employees e INNER JOIN departments d ON e.department_id=e.department_id INNER JOIN jobs j ON e.job_id=j.job_id ORDER BY department_name DESC;
#inner在输入的时候可以省略
#筛选条件放在where后面 连接条件放在on后面
#非等值连接
#查询员工工资的级别
SELECT salary,grade_level FROM employees e JOIN job_grades g ON e.salary BETWEEN g.lowest_sal AND g.highest_sal;
#查询工资级别个数>2的个数,并且按工资级别降序
SELECT COUNT(*),grade_level FROM employees e JOIN job_grades g ON e.salary BETWEEN g.lowest_sal AND g.highest_sal GROUP BY grade_level HAVING COUNT(*)>20 ORDER BY grade_level DESC;
#自连接
#查询员工的名字,上级的名字
SELECT e.last_name,m.last_name FROM employees e JOIN employees m ON e.manager_id=m.employee_id;
#外连接(查两表的非交集部分,将两表看成主从表,left join 左边为主表 right join 右边为主表)
#查询男朋友不在男生表的女生名
SELECT b.name,bo.* FROM beauty b LEFT JOIN boys bo ON b.boyfriend_id=bo.id WHERE bo.id IS NULL;#主键不可能是空
SELECT b.name,bo.* FROM boys bo RIGHT JOIN beauty b ON b.boyfriend_id=bo.id WHERE bo.id IS NULL;#右外连接
#查询哪个部门没有员工
#先考虑哪个是主表
#部门表为主表
SELECT d.*,e.employee_id FROM departments d LEFT OUTER JOIN employees e ON d.department_id=e.department_id WHERE e.employee_id IS NULL;
#全外连接MySQL不支持
#select b.*,bo.* from beauty b full outer join boys bo on b.boyfriend_id=bo.id;
#全外连接=内连接结果+表1有表2无+表1无表2有

#交叉连接(就是迪卡尔乘积)
SELECT b.*,bo.* FROM beauty b CROSS JOIN boys bo;
#建议使用sql99语法,实现连接条件和筛选条件进行分离
#内连接实现的是两表交集,左外实现的是一表中可去掉交集部分,右外同理。全外实现的是全表

#子查询:出现在其他语句中的select语句,称为子查询或内查询
#子查询语句可以放在select后面ffrom后面where后面having后面exists后面
#标量子查询(结果只有一列一行),列子查询(结果只有一列多行),行子查询(结果只有一行多列)表子查询(结果为多行多列)
#select 后面只支持标量子查询 from后面支持表子查询 where和having后面支持标量子查询和列子查询,行子查询,exists后面支持表子查询
#标量子查询又叫单行子查询
#子查询都会放在小括号内
#1.标量子查询
#谁的工资比Abel 高?
SELECT salary FROM employees WHERE last_name='Abel';
SELECT * FROM employees WHERE salary>(SELECT salary FROM employees WHERE last_name='Abel');#子查询语句不要加分号
#返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id 和工资
SELECT job_id FROM employees WHERE employee_id=141;
SELECT salary FROM employees WHERE employee_id=143;
SELECT last_name,job_Id,salary FROM employees WHERE job_id=(SELECT job_id FROM employees WHERE employee_id=141) AND salary>(SELECT salary FROM employees WHERE employee_id=143);
#返回公司工资最少的员工的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 );
#查询最低工资大于50号部门最低工资的部门id和其最低工资
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);
#子查询的执行,优先于主查询的执行
#列子查询又叫多行子查询
#in意思是in后面中的任意一个
#多行操作符:in not in any some all
#字段 in(列表值)
#字段 in(查询语句)
#any 和some都代表任意的意思
#字段>any(列表或子查询) some 用法同理 可用字段>min()
#all 都的意思 字段>all(列表或子查询) 可用字段>max()
#返回location_id是1400或1700的部门中所有员工的姓名
SELECT last_name FROM employees e,departments d WHERE e.department_id=d.department_id AND d.location_id IN(1400,1700); 
SELECT department_id FROM departments WHERE location_id IN(1400,1700);
SELECT last_name FROM employees WHERE department_id IN(SELECT department_id FROM departments WHERE location_id IN(1400,1700););#子查询语句中有分号会报错
SELECT last_name FROM employees WHERE department_id IN(SELECT department_id FROM departments WHERE location_id IN(1400,1700));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值