mysql -u用户名 -p密码
查看数据库 注意以分号结尾
show databases;
#显示全部数据库,(#是mysql注释的符号)java
_____________________________________________________________________________________
SQL(Structural query language) 结构化查询语言,用于操做数据库
SQL学习的三条主线mysql
#SQL的学习分为以下的三部分: #DML :数据操纵语言 ---> INSERT / DELETE / UPDATE / SELECT ----增删改查 #DDL :数据定义语言 ---> CRAETE(加一个列) / ALTER (修改)/ DROP(删除) / TRUNCATE (清空)/ RENAME(重命名) #DCL :数据控制语言 ---> COMMIT 提交数据) / ROLLBACK(回滚操做) / GRANT / REVOKE #说到数据库,习惯上提到增删改查,数据库的增删改比较简单,查询比较难一些 #数据量大能够用limit分页显示,好比:查询五百条数据,十条十条显示
_____________________________________________________________________________________
基本的SELECT语句;web
elect 查询的列 from 查询的表` show databases; use test1 #有些字段为 null 和java的null是一个意思就是没有赋值的意思,NULL和0是两个概念 select name myname , age as myage from myname #为查询后表的字段指定别名 可用 字段名 别名 的形式 #或者 字段名 as 别名 的形式
#注意全部"," 全都是半角的
#若是列的别名中想要包含空格 则用"别 名"或’别 名’引发来
#规范里要求用双引号,mysql里不严格 oracle数据库里必须是双引号sql
SELECT hid H_ID,gname AS "GAME NAME" FROM girl;
#查询全部的数据库
SHOW DATABASES;
#使用指定的数据库
USE test1;
数据库
#基本的查询操做,查哪一个列,哪些列api
SELECT hid,gname #要查询字段 FROM girl; #要查询的表
查询的快捷键是F9
查询此表中的所有的列
SELECT *
FROM girl;
服务器
#列的别名
#可使用一对""包裹别名网络
SELECT hid 'H ID',gname AS "游戏 昵称" FROM girl;
#三类常见的数据类型:oracle
#1数值型,java的整型浮点型 #2字符型/字符串型,姓名,街道,省份 没有严格要求说字符就是一个,字符串就是多个 #3日期型 #除此之外还有不少 #日期型和字符型变量。要使用一对 单引号来引用,只能在单引号中出现 #双引号是给列起别名是使用
#显示表结构
#对应改变表
#显示字段名 数据类型 是否为空 key default extra字段属性
#图形化界面至关于选中表之后,右键,改变表svg
DESC girl;
#命令行显示表结构
#或者使用命令全称
DESCRIBE girl;
比较运算 操做符 含义 = 等于(不是==) > 大于 >= 大于、等于 < 小于 <= 小于、等于 <> 不等于(也能够是!=) 重点 : 赋值使用 :=符号
#其余比较运算符
操做符 含义 BETWEEN 在两个值之间(包含边界) ... AND ... IN(set) 等于值列表中的一个 LIKE 模糊查询 IS NULL 空值
在sqlyog中将光标定位在某个查询语句上,就能够执行当前的查询
sql 中的字符理解成字符串
逻辑运算 操做符 含义 AND 逻辑并 (且) OR 逻辑或 (或) NOT 逻辑否 (非)
#mysql 刚安装完初始化的数据库有4个
#比较关键的是mysql 这里放的是系统相关的表
#用户名,密码都在这里,密码是加密过的
_____________________________________________________________________________________
#1 过滤 2 排序
#查询 test1 数据库中表 goods 中全部cat_id 是8的信息,并返回
SELECT * FROM goods #过滤数据 WHERE cat_id=8;
#查询shop_price > 60的货物 SELECT goods_name,cat_id,shop_price FROM goods #WHERE (shop_price > 3000 or shop_price < 2000) ; WHERE shop_price != 1000;
#between …and … (在两个值之间,包含边界)
SELECT * FROM goods #where shop_price between 2000 and 3000; WHERE shop_price BETWEEN 3000 AND 2000; #包含边界时用between and 比较方便,不包含时仍是使用 >=之类的操做符比较简单
#in (set ) :取值为()中的任一个
SELECT * FROM goods #where shop_price=2000 or shop_price=2500 or shop_price=3000; WHERE shop_price IN( 2000,2500,3000 );
#like :模糊查询 查询goods表 goods_name 包含a的数据
SELECT * FROM goods #where goods_name like '%p%e%' or goods_name LIKE '%e%p%';
#此处谁like 要写全 写具体
#%号表明0个或多个字符
#oracle 在单引号引的里边是区分大小写的
#WHERE goods_name LIKE ‘%p%’ and goods_name LIKE ‘%e%’;
#查询goods_name 第二个字符是a的数据
WHERE goods_name LIKE ‘_d%’; #mysql 中 _是占位符,一个下划线表明一个字符’___d%'第四个字符是d
#什么字符均可以,任意一个字符
#查询第二个字符是,且第三个字符是a的数据
#转义字符 \
SELECT * FROM girl #where gname like '%\_%女'; WHERE gname LIKE '%_%女' ESCAPE '_'; #ESCAPE '_' 是指定转义字符的意思,因此转义有两种方法
#is null :空值
#is not null :非空值
SELECT * FROM girl WHERE gname IS NOT NULL; SELECT goods_name, goods_id,market_price,goods_number , (market_price * goods_number) AS '可得销售总额' #指定一个新列,字段为总额,内容是乘积 #凡是null值参与运算,结果都是null,应该明白,null就是null 不等同于0,若是想把null 当成0 能够用函数来实现 FROM goods;
#排序 分组 order by
SELECT * FROM goods #Order By market_price;
#Order by 默认按升序排序 #也能够本身指定排序方式 #ASC : 升序 (ascend) 也能够省略不写 #Desc : 降序 (descend) ORDER BY market_price DESC;
#若是想在排序的同时作一些过滤操做,那么 where 不能乱放,不能放在order by 的后边 #where一般和from 挨着, #from后边紧跟着where,order by 写的时候一般写在查询语句的最后
#查询 goods_number >10 的 market_price 降序以后的数据 SELECT * FROM goods WHERE goods_number>10 ORDER BY market_price DESC;
#二级排序
SELECT * FROM goods WHERE goods_number>10 ORDER BY market_price DESC,click_count; #若是一级排序结果比较多,那么就能够指定二级,三级,n级排序 #就在原先的排序条件后加 ,条件便可
#可使用别名排序
SELECT goods_name AS GOODSNAME #指定别名 FROM goods WHERE goods_number>10 ORDER BY GOODSNAME; #按别名排序
_____________________________________________________________________________________
#实现多个表之间的查询
#涉及到多个表链接
#多表链接,多表查询
#为何不把全部信息都放一张表里,乱,杂,管理起来不方便,如同java中类
#create database 学生信息; USE 学生信息; SELECT 姓名,对应地址 FROM 基本信息,区域表;#30行 6*5=30
#以上查询是错误的,称这种错误为:笛卡尔集错误。
#没有写两个表的链接条件,或写条件了,但失效了
#若是多表链接中,没有声明多表链接条件或链接条件失效。
#直角坐标系,又叫笛卡尔坐标系
SELECT 30/6 FROM DUAL; #dual是虚拟表
#正确的,多表链接,必定会有链接条件
USE 学生信息; SELECT 姓名,对应地址 FROM 基本信息,区域表 #链接条件 WHERE 基本信息.`区域编号`= 区域表.`区域编号`; #关联的语法是 表1.字段名=表2.字段名,若是两个字段名相同,则关联成功 #知足链接条件的显示出来了,
#错误示范
USE 学生信息; SELECT 姓名,对应地址,区域编号#此时这个区域编号是基本信息表里的呢,仍是区域表里的呢 #产生了二义性,因此报错ambiguous,此时的解决办法是指定具体的表 #用表.区域编号来表示 #select 后边的两个字段 姓名和对应地址都惟一的存在对应的两个表中,很好查找 #若是查询的列在多个表中都出现 #则必定要指明此列所属的表 #最好是查询时每一列都指明表, #从SQL优化的角度说,指定所属表的字段效率比较高 #mysql高级课中有优化等其余操做 FROM 基本信息,区域表 WHERE 基本信息.`区域编号`= 区域表.`区域编号`; #ambiguous 不肯定的模糊的
#表的别名
USE 学生信息; SELECT e.姓名 , d.对应地址 FROM 基本信息 AS e ,区域表 d #链接条件 WHERE e.`区域编号`= d.`区域编号`; #若是指定别名则用别名操做,不能用原有名称操做,指定别名也可用AS
#列的别名只能使用在 order by,其余地方很差使 #因此说列的别名只能用来排序,不能用来过滤
#查询具体地址操做三个表
SELECT e.姓名 , d.`区域编号` ,f.具体地址 FROM 基本信息 AS e , 区域表 AS d , 地址表 AS f WHERE e.`区域编号`=d.`区域编号` AND d.`地址编号`=f.`地址编号`; #三个表写两个链接条件 #等值链接,两个表必须有共同字段
#总结1:若是有N个表作查询操做,那么链接条件至少有N-1个
#总结2:表的链接分类
#等值链接 VS 非等值链接 #自链接(本身链接本身) VS 非自链接(本身链接别人) #内链接 VS 外链接
#非等值链接基本信息
SELECT 基本信息.`姓名`,基本信息.`年龄`,工资等级.`等级` FROM 基本信息,工资等级 #where 基本信息.`工资`>=工资等级.`从` and 基本信息.工资<=工资等级.到; #协程between and 比较清晰 WHERE 基本信息.工资 BETWEEN 工资等级.从 AND 工资等级.`到` #查询完对结果工资等级进行降序排序 ORDER BY 工资等级.`等级` DESC;
#以上写的都是非自链接
#自链接(本身链接本身)
#查询 每一个员工及其管理者的信息
SELECT emp.工号 ,emp.`姓名` , mgr.`工号`,mgr.`姓名` FROM 基本信息 emp , 基本信息 mgr #操做两个表,实质是一个表 WHERE emp.`上司工号`=mgr.`工号`; #查询完输出顺序发生了改变
#这是个没用的例子 SELECT 基本信息.`工号`,基本信息.`上司工号` FROM 基本信息;
#内链接:内链接: 合并具备同一列的两个以上的表的行
#结果集中不包含一个表与另外一个表不匹配的行
#内链接:只查询链接条件能匹配的行的信息,
#结果集中不包含不匹配的行
USE 学生信息; SELECT e.姓名 , d.`地址编号` FROM 基本信息 AS e ,区域表 d #链接条件 WHERE e.`区域编号`= d.`区域编号`; #此表中 贝贝的区域编号为空,因此被过滤掉了
#外链接: 两个表在链接过程当中除了返回知足链接条件的行
#之外还返回左(或右)表中不知足条件的行 ,
#这种链接称为左(或右) 外链接。没有匹配的行时,
#结果表中相应的列为空(NULL).
#外链接
#左外链接 :除了能查询到知足链接条件能匹配的信息行以外,还能查到左表中不知足条件的信息
#右外链接 :除了能查询到知足链接条件能匹配的信息行以外,还能查到右表中不知足条件的信息
#外链接查询到数据的数量要大于等于内链接查询到的数据的数量
#USE 学生信息; #SELECT e.姓名 , d.`地址编号` #FROM 基本信息 AS e ,区域表 d #链接条件 #WHERE e.`区域编号`= d.`区域编号`(+); #使左右表长度同样 #oracle比较简单,加个+就表示左外链接,而mysql不能实现
#查询全部员工的姓名,地址编号(有人地址编号为空)
#mysql 外链接只能借助join on,其余链接,join on 和 where均可以 #sql 99的语法,规定了另外一种方式,实现多表的链接 #内链接 SELECT e.姓名 , d.`地址编号` FROM 基本信息 e JOIN 区域表 d #链接条件 ON e.`区域编号`=d.`区域编号`; SELECT 工号`区域表`,姓名,地址编号 FROM 基本信息 j JOIN 区域表 q #加入一个表 ON j.`区域编号` = q.`区域编号`; #链接条件 #where....若是还有过滤条件加where
#三个表的内链接
SELECT 工号`区域表`,姓名,q.地址编号 FROM 基本信息 j JOIN 区域表 q #加入一个表 ON j.`区域编号` = q.`区域编号` #链接条件 JOIN 地址表 AS l ON q.`地址编号`=l.`地址编号`; #join #on 多个表就 一直join on 下去 #加入INNER 关键字,一样表示内链接 SELECT 工号`区域表`,姓名,q.地址编号 FROM 基本信息 j INNER JOIN 区域表 q ON j.`区域编号` = q.`区域编号` #链接条件 JOIN 地址表 AS l ON q.`地址编号`=l.`地址编号`;
#使用sql 99语法实现外链接
#在 JOIN 的左侧加入 LEFT OUTER 叫左外链接 SELECT 工号`区域表`,姓名,地址编号,q.`区域特点` FROM 基本信息 j LEFT OUTER JOIN 区域表 q #加入一个表 ON j.`区域编号` = q.`区域编号`; #链接条件 #where....若是还有过滤条件加where #列出左表的所有信息
#右外链接
SELECT 工号`区域表`,姓名,地`区域表`址编号,q.`区域特点` FROM 基本信息 j RIGHT OUTER JOIN 区域表 q #加入一个表 ON j.`区域编号` = q.`区域编号`; #链接条件 #where....若是还有过滤条件加where #把两个表匹配的信息列出来后,把右表中不知足条件的也列出来 #至关于列出右侧表的所有信息 #即包含左表不知足的,又包含右表不知足的 #满外链接:除了查询到知足链接条件能匹配的行的信息以外, #还能查询到左表和右表中不知足条件的信息。 #oracle支持满外链接。使用full关键字实现,mysql不支持 #mysql 若是想实现一样的功能,只能多个表去求unio,并
#SELECT 工号`区域表`,姓名,地`区域表`址编号,q.`区域特点` #FROM 基本信息 j full OUTER JOIN 区域表 q #加入一个表 #ON j.`区域编号` = q.`区域编号`; #链接条件 SELECT 工号`区域表`,姓名,地`区域表`址编号,q.`区域特点` FROM 基本信息 j RIGHT OUTER JOIN 区域表 q #加入一个表 ON j.`区域编号` = q.`区域编号`; #链接条件
_____________________________________________________________________________________
#单行函数
#sql 相似于java 中的方法
#y=f(x1,x2…n)
#单行函数:一个输入一个输出的函数叫单行函数
#多行函数:多个输入一个输出的函数叫多行函数
#行 : 表中的一行数据
#进去一行出来一行,就是单行函数
#进去多行,出来一行,就是多行函数 进去多个工资,出来一个最高的
#单行函数 操做数据对象
#单行函数
#数据库对象:表(table) 视图(view)索引(index)
#序列(sequence) 函数(FUNCTION) 存储过程(PROCEDURE) 触发器(trigger)
#像java 类同样
#视图:不一样于表,视图修改对应数据,会更新源数据
#索引:为了快速查找,表中数据达到几十万条,快速找到想要的,能够为表建立索引
#序列:添加数据时,让序列自动添加,每次隔着几个数,好比 1 3 5 7
#函数,相似于java无返回值的方法
#存储过程,相似于java有返回值的方法
#触发器:作以下相似的操做,删除数据时每删除一条触发一条,能够用做复制,备份
#工做中 不是作DBA 因此不用深究函数这三个结构
#单行函数
#操做数据对象
#接受参数返回一个结果
#字符函数
SELECT 'hello','heLLo',LOWER('heLLo'),UPPER('hello') FROM DUAL; #没有存在任何表中就写一个DUAL
USE 基本信息; SELECT * FROM 基本信息 WHERE LOWER(姓名) = LOWER('KING');#假如数据库是时小写的 #sql 标准严格字符区分大小写 mysql 并无这么严格,忽略了大小写
SELECT CONCAT('AAA','bbb','ccc') FROM DUAL;
#xxx worked for xxx
SELECT CONCAT(emp.`姓名` ,' worked for ' , mgr.`姓名`) AS '工做信息' FROM 基本信息 emp , 基本信息 mgr #操做两个表,实质是一个表 WHERE emp.`上司工号`=mgr.`工号`;
#该方法特色是 从第二个参数开始,取第三个参数长度的子串
SELECT SUBSTR('HelloWorld',2,5)#mysql 索引位置是从1 开始的 #java JDBC操做数据库,一些api中的数据库索引也是从1开始 FROM DUAL; #LENGTH() 长度 #INSTR() 字符在串中首次出现的位置,没有出现则输出0 #LPAD() SELECT INSTR('helloworld','l') FROM DUAL;#3 #LPAD("he",10,' ') 右对齐 十位,不足补' ' #RPAD('he',10,' ')左对齐 #TRIM('h' FROM 'helloh' ) 取什么均可以,这里去了收尾的h FROM DUAL;
SELECT TRIM(' ' FROM 'helloh') FROM DUAL; #REPLACE('abcd','b','m') 替换了,所有被替换
#数学函数
SELECT ROUND(12.345,0),ROUND(12.345,2),ROUND(12.34,-1) FROM DUAL; #ROUND 四舍五入 第三个参数是-1时,结果是10 2被四舍五入了 #第三个参数若是是0能够去掉,是默认行为
SELECT TRUNCATE(12.345,0),TRUNCATE(12.345,2),TRUNCATE(12.34,-1) FROM DUAL; #truncate()是截断 以上结果分别为 12 12.34 10 #MOD(12,5) 求余能够有正负状况 SELECT MOD(12,7),MOD(-12,7),MOD(12,-7),MOD(-12,-7),MOD(12.3,3) FROM DUAL; #以上结果 5 -5 5 -5 0.3
#日期函数
#函数now() 返回:日期,时间 SELECT NOW() , DATE(NOW()), TIME(NOW()),SECOND(NOW()),MINUTE(NOW()),HOUR(NOW()), DAY(NOW()),MONTH(NOW()) , YEAR(NOW()) FROM DUAL;
#通用函数
SELECT (goods_price*IFNULL(goods_number,0)) #ifNULL(expr1,expr2) 若是第一个参数是0,那么就拿第二个参数替换第一个参数 FROM DUAL; #oracle 使用的是nvl替换
#条件表达式
#case WHEN then then then else end
#查询全部员工信息,
#若其年龄 打印其工资的10倍
#若其年龄 打印其工资的20倍
#若其年 打印其工资的30倍
#如果其余年龄 打印其工资
#格式以下:
SELECT 工号,工资,CASE 年龄 WHEN 10 THEN 工资*10 WHEN 20 THEN 工资*20 WHEN 30 THEN 工资*30 ELSE 工资 END AS '新工资' FROM 基本信息; #能够没有ELSE #where 。。。 能够指定where过滤 #case when then 之间没有任何标点
#多行函数(分组函数)
#好比查询工资最大值
#经常使用分组函数:avg() sum() max() min() count()
#avg() sum() 只针对数值型变量操做,其余类型不能够
#不能够操做字符型,日期型变量
#求工资平均值,和
SELECT AVG(工资) ,SUM(工资) FROM 基本信息; #mysql 对某些无心义操纵不报错,这一点oracle作的比较好
#max() , min() 针对数值型,字符型,日期型操做
SELECT MAX(工资),MIN(工资),MAX(姓名) , MIN(姓名) FROM 基本信息;
#count() 计算指定列数据中非空数据的个数
SELECT COUNT(姓名) ,COUNT(NULL),COUNT(1),COUNT(*)#1取出一条数据看看是否是NULL, FROM 基本信息; #avg=sum/count 他们求的都是非空数据不考虑控制 SELECT AVG(工资) , SUM(工资), SUM(工资)/COUNT(工资) FROM 基本信息; #sum(工资)/count(*) ,AVG(IFNULL(工资,0)) #group by 实现对各个部门进行分组计算各个组的平均工资
SELECT department_id,AVG(salary) FROM employees GROUP BY department_id;#按组id进行分组求平均 #好比国家计算我国各个行业的平均工资是多少 #学校计算每一个院系收的总学费是多少
#group by 指定要分组的列便可 SELECT COUNT(姓名),区域编号#求各个区域的人数 FROM 基本信息 GROUP BY 区域编号;
#不一样部门,不一样工种的平均工资 SELECT department_id,AVG(salary) FROM employees GROUP BY department_id,job_id;
SELECT department_id,AVG(salary) FROM employees ###这种写法即便能出来数据,但不是正确的 ###没有什么意义 mysql这么写不报错,oracle 会报错 #凡是在select 中,有组函数 也有非组函数 #要求,非组函数必定要出如今咱们的group by当中
#错误的
SELECT department_id,AVG(salary) FROM employees GROUP BY department_id;
#正确的:反之,出如今group by中的列能够不声明在select中。
SELECT department_id,AVG(salary) FROM employees GROUP BY department_id,job_id;
#在select 中有组函数和非组函数的列,那么非组函数的列必定要在group by 中声明
#进行这组操做
#having
#非法使用组函数
#部门最高工资比10000高的部门
SELECT department_id,MAX(salary) FROM employees #where max(salary)>10000 #出错了,凡是在过滤条件中,使用组函数的话,那么须要使用 #having 替换掉where GROUP BY department_id;
#orcale这样写能够,可是mysql不行
SELECT department_id,MAX(salary) FROM employees HAVING MAX(salary) >10000 GROUP BY department_id;
#mysql要求把having声明在group by的 后边,oracle没有此要求
SELECT department_id,MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary) >10000;
#查询 10 20 30 40 50部门中,哪些部门的最高工资比10000高
#效率低
SELECT department_id,MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary) >10000 AND department_id IN (10 ,20 , 30 , 40 ,50); #这种写法不会报错,可是不建议这么写 #若是有多个过滤条件,必须将分组函数的过滤条件写在having中。 #另外,不包含组函数的过滤条件建议写在where中。由于写在where中效率更高
#sql优化,效率高
SELECT department_id,MAX(salary) FROM employees WHERE department_id IN (10 ,20 , 30 , 40 ,50) #where在全表检索的时候就已经开始过滤 #having 全表检索完之后才开始过滤,效率低。 GROUP BY department_id HAVING MAX(salary) >10000 ;
#总结:
#至此,关于关键字的使用在select中就已经结束了
#select 。。。。。,。。。。。,。。。。。别名 #from 。。。,。。。,。。。。 join 。。。。。 #on 。。。。。。。。。。。。。 #join 。。。。。。。。。。。。 #where 多表的链接条件 #and 非组函数的过滤条件 #group by 。。。。。。。。。 #having 。。。。。。。。。。 #order 。。。。。。。。。。。 #limit 。。。。。。。。。。。 分页
_____________________________________________________________________________________
#子查询,就是嵌套select ,嵌套多层,有时能够优化
#谁的工资比 张三高
#方式一:
#屡次查询
USE 学生信息; SELECT 姓名,工资 FROM 基本信息 WHERE 姓名='张三'; SELECT 姓名,工资 FROM 基本信息 WHERE 工资 > 1034;
#方式二:
#自链接
#并非全部问题都是自链接都能解决的
SELECT j2.`姓名`,j2.`工资` FROM 基本信息 AS j1, 基本信息 AS j2 WHERE j1.`姓名`='张三' AND j1.工资<j2.工资;
#方式三
#子查询
#在java jdbc 调用服务器后台数据库时,力求
#简洁,能一次作完的事情,毫不分红两次作完。
SELECT 姓名,工资 FROM 基本信息 WHERE 工资 > ( SELECT 工资 #不能写多余的信息 FROM 基本信息 WHERE 姓名='张三' );
#两个以上嵌套的查询都叫子查询
SELECT 姓名,工资 FROM 基本信息 WHERE ( SELECT 工资 #不能写多余的信息 FROM 基本信息 WHERE 姓名='张三' )<工资; #也能够这么写,可是看着很别扭 #通常都是把轻量级的变量放在where 位置
#子查询分类
#单行子查询:返回一行查询记录
SELECT 姓名,工资 FROM 基本信息 WHERE ( SELECT 工资 #不能写多余的信息 FROM 基本信息 WHERE 姓名='张三' )<工资;
#由内向外
#多行子查询:返回多行查询记录
#返回 基本信息表中区域编号和斯蒂文相同,
#工资比小倩多的员工的姓名,工号,和工资
#解决方式,1 从外往里写, 2 从里往外写
SELECT 姓名,工号,工资 FROM 基本信息 WHERE 区域编号=( SELECT 区域编号 FROM 基本信息 WHERE 姓名='斯蒂文' ) AND 工资>( SELECT 工资 FROM 基本信息 WHERE 姓名='小倩' );
#通常来说 从里往外写 比较简单一些
#从外往里写,不能够测试
#返回公司工资最少的员工的姓名,工号,工资
SELECT 姓名,工号,工资 FROM 基本信息 WHERE 工资= ( SELECT MIN(工资) FROM 基本信息 );
#返回公司工资第二少的员工的姓名,工号,工资
SELECT 姓名,工号,工资 FROM 基本信息 WHERE 工资=( SELECT MIN(工资) FROM 基本信息 WHERE 工资>( SELECT MIN(工资) FROM 基本信息 ) );
#自查询中带有having
#查询最低工资大于60号部门最低工资的部门id和其最低工资
SELECT department_id ,MIN(salary) FROM empoyees GROUP BY department_id HAVING MIN(salary)>( SELECT MIN(salary) FROM employees WHERE department_id=60 ) AND department_id IS NOT NULL;
#看的时候也由内往外看,说的时候从外往里说
#要学会英汉互译
#非法使用子查询
#…
SELECT employee_id, last_name FROM employees WHERE salary = #这里应该用In (SELECT MIN(salary) FROM employees GROUP BY department_id); **#子查询中的查询结果空值问题** SELECT last_name, job_id FROM employees WHERE job_id = (SELECT job_id FROM employees WHERE last_name = 'Haas'); #公司没有这个工种以及这我的,查无此人
#多行子查询,可使用的操做符为:in any all
SELECT employee_id, last_name FROM employees WHERE salary IN (SELECT MIN(salary) FROM employees GROUP BY department_id);
#any
#题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员
#工号、姓名、job_id 以及salary
SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ANY # any (SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
############### ##DISTINCT去重# ###############
#题目:返回其它部门中比job_id为‘IT_PROG’部门任意工资低的员工的员
#工号、姓名、job_id 以及salary
SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ALL # any (SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
#最困难的就是子查询
#查询工资比公司平均工资高的员工的员工号,姓名和工资。
SELECT employee_id,last_name,salary FROM employees WHERE salary>( SELECT AVG(salary) FROM employees );
#*.查询各部门中工资比本部门平均
#工资高的员工的员工号, 姓名和工资
#相关查询
#方式一:
SELECT employee_id,last_name,salary FROM employees e1 WHERE salary>( #查询送进来的员工所在部门的平均值 SELECT AVG(salary) FROM employees e2 WHERE e1.`department_id`=e2.`department_id` );
#外边先送进来一条数据
#里边判断,和送进来的比较一下而后再送出去
#方式二:子查询不止能够出如今where过滤条件中
SELECT employee_id,last_name,salary #下边至关于新制做了一张表 FROM employees e1,(SELECT department_id,AVG(salary) dept_avg_sal FROM employees GROUP BY department_id) d) WHERE e1.`department_id`=d.dept_avg_sal;
#子查询不只能够写在where 里,能写的地方比较多
#group by 这块不能写其余地方均可以写
#排序这块也能够写
#能够在order by 中也使用子查询
#查询员工的姓名,部门id,要求按照部门名排序
SELECT last_name,department_id FROM employees e ORDER BY ( SELECT department_name FROM departments d WHERE e.`department_id`=d.`department_id` );
#查询管理者是King 的员工的姓名和工资
SELECT last_name,salary FROM employees WHERE manage_id IN( SELECT employee_id FROM employees WHERE last_name='King' );
#查询平均工资最低的部门信息
#单行函数能够嵌套,多行行数,分组函数不能够嵌套
#oracle能够嵌套
SELECT MIN(AVG(salarg)) FROM employees GROUP BY department_id
#mysql 写法
SELECT * FROM departments WHERE department_id=( SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary)=( SELECT MIN(avg_sal) FROM( SELECT AVG(salary) avg_sal FROM employees GROUP BY department_id ) dept_avg_sal ) );
#查询平均工资最低的部门的信息和该部门的平均工资
SELECT d.*,(SELECT AVG(salary) FROM emeployees e WHERE e.department_id=d.`department_id`) "部门平均工资" FROM departments d WHERE department_id=( SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary)=( SELECT MIN(avg_sal) FROM( SELECT AVG(salary) avg_sal FROM employees GROUP BY department_id ) dept_avg_sal ) );
#各个部门中 最高工资中最低的那个部门的 最低工资是多少?
#加入有三个部门 最高工资分别是 8000 9000 10000, 那么本题求的是8000那个部门的最低工资
SELECT MIN(salary) FROM employees WHERE department_id=( SELECT department_id FROM employees GROUP BY department_id HAVING MAX(salary)=( SELECT MIN(max_sal) FROM ( SELECT MAX(salary) max_sal FROM employees GROUP BY department_id ) dept_max_sal ) )
#分号问题,若是把下边的所有选中,那么会逐个执行插入操做
#分号表示单独一条的执行语句,单独一行的代码写不写分号都无所谓
INSERT INTO ....; INSERT INTO ....; INSERT INTO ....; INSERT INTO ....;
_____________________________________________________________________________________
#写查询时最好一次性都作完,一次性搞定
#查询不可难免的使用子查询
#sql三条主线 #DML :inset、update ,delete,select #DDL : create、alter、drop、truncate、rename #dcl :commit、rollback
#主要学ddl
#显示全部的数据库 SHOW DATABASES; #使用指定的数据库 USE 学生信息;
#显示全部的表
SHOW TABLES;
#建立表 (create table) #方式一:"白手起家的方式",本身一点点搭建起来 #HOW TO CREATE TABLE ? #CREATE TABLE CREATE DATABASE AAA; USE AAA;
#设计每一个字段
#列,即字段,要指定字段的数据类型
#数据类型 等比java严格
#设置长度10位 最大9999999999
#字符型
#工资,总长度是10,其中2位是小数
#入职时间,日期型
#开发中建立表的方式
CREATE TABLE myemp1( emp_id INT(10) AUTO_INCREMENT PRIMARY KEY, emp_name VARCHAR(15), salary DOUBLE(10,2), hire_date DATE ); SELECT * FROM myemp1 ; DESC myemp1;
################## #AUTO_INCREMENT # 自增加,建立一个本身增长 ################## #PRIMARY KEY # 设置主键 保证自动添加的数是惟一的 ##################
#平时建立表的时候,用到约束,
#方式二: “基于现有的表,建立新的表”,创二代,富二代
CREATE TABLE myemp2 AS #列的别名充当新建立键的表的列名 SELECT employee_id emp_id ,last_name,salary #emp_id是列的别名,建立别名后新表中使用这个别名做为字段 FROM employees;
#从原有的表中复制出来三个字段供myemp使用
#原表的类型和存储范围也同步的复制过来了
#并非全部内容都会被赋值过来
#约束并非能被复制过来的
#此种方式建立表的同时,还能够将原有表的数据赋值过来
SELECT * form myemp2;
#不能覆盖,因此要写个别的名
CREATE TABLE myemp3 AS SELECT employee_id emp_id ,last_name,salary FROM employees; WHERE department_id IN (50 , 60 , 70,80) AND salary > 5000;
#能够根据本身的想法,创造不少的新表
CREATE TABLE myemp4 AS SELECT department_id ,AVG(salary) FROM employees GROUP BY department_id;
#####基于多表建立新表
CREATE TABLE myemp5 AS SELECT department_name ,AVG(salary) FROM employees e, departments d WHERE e.department_id = d.department_id GROUP BY department_name;
#复制 employees
CREATE TABLE employee_copy AS SELECT * FROM employees; ##约束有一些问题
#复制 employees ,可是数据为空
CREATE TABLE employee_blank AS SELECT * FROM employees; ##约束有一些问题 WHERE 1=2; #写个不成立的条件
#建立表涉及到一些经常使用的数据类型
#varchar()
#不写长度会报错 一般用这种可变长度的
#视频,图片都是以blog形式存储的
#有多种不一样的blog
#改变表
USE aaa; CREATE TABLE myemp1( emp_id INT(10) AUTO_INCREMENT PRIMARY KEY, emp_name VARCHAR(15), salary DOUBLE(10,2), hire_date DATE );
#修改表 (alter table)
#1添加一个列
ALTER TABLE myemp1 ADD email VARCHAR(25); DESC myemp1; #ora varchar2 mysql varchar
#修改现有的列
ALTER TABLE myemp1 MODIFY salary DOUBLE(15,2) DEFAULT 2000; #default 用于设置默认值 #modify用于修改表字段
#删除现有列
ALTER TABLE myemp1 #不能用delete,delete用于删数据 #这里用drop 删除结构 DROP COLUMN email; #colum叫列
#重命名列
#能够同时改变列数据类型 #和ora 不同 #change USE aaa; ALTER TABLE myemp1 CHANGE salary my_sal DOUBLE(10,2);
#oracle 的写法 : #alter table myemp1 rename salary to mysal; #修改四个事情 完毕
#删除表
DROP TABLE myemp1;
#重命名表
ALTER TABLE emp3 RENAME TO myemp1; #oracle : rename myemp3 to emp3; SELECT * FROM myemp3; SELECT * FROM emp3;
#最后一个操做
#清空表
#清空表:将表中全部的数据清空,表结构仍然保留
#truncate table
一旦将数据删除,数据不可回滚
#delete from
: 删除操做支持回滚 增删改的删
COMMIT; #提交数据
#前边作的任何修改都提交,
#以前作的修改都保存下来
##DCL
#将数据设置为不能自动提交
USE 学生信息; SET autocommit=FALSE;#不让数据提交 DELETE FROM 地址表; SELECT * FROM 地址表; ROLLBACK ; #回滚数据 ROLLBACK ;#只会回滚到最近的一次commit以后,他俩是成对出现的 ############# COMMIT; SET autocommit=FALSE; TRUNCATE TABLE test1.`result`; ##不可回滚数据,也能够理解为自动提交数据 #一旦执行不可找回 ROLLBACK; SELECT * FROM test1.`result`;
回滚这里有坑
#有时没法回滚
#解决办法
https://blog.csdn.net/noaman_wgs/article/details/52121991
_____________________________________________________________________________________
#pl/sql专门的数据库操做语言,
#增删改查中查询最复杂也最重要
#和数据库交互时,力求查询命令写的干净利落,一次能完成的事情,毫不两次作完
#相关子查询是里边和外边有相关性,外边传进去,里边再传出来,用到子查询
#建立管理表要简单一些,建立表有两种方式,白手起家,和拷贝
#修改表有四个指令,添加列,修改列,删除列等,修改列名操做比较少,通常状况下数据库表字段都是一次成型,改列名的操做不多去作
#存储范围从小改大不会对原数据形成影响,由大改小会形成数据丢失,报错
#数据类型也能够修改,自己已经有数据,由double改data 那么不匹配,在oracle报错,表中没数据能够改,在mysql中不报错
#若是里边有数据,也会改为功,会清空数据。这一列数就全没有了。
#清空表turnccate table,不可回滚
#表很是肯定,想要删除,用trunccate table
#delete from 中间环节是删一删,修改一下,不肯定。
#增删改均可回滚。及时commit 提交数据 省着回滚的特别远,形成数据损失
#函数 格式很重要
#sql 不难,须要多写
#没有很长的代码,撑死几十行
#投入了会心疼,会努力
#group by 后不要写子查询
#数据处理 之 增删改
#增 (添加) -----INSERT INTO
DROP TABLE aaa.`myemp1`;
USE aaa; CREATE TABLE myemp( id INT, nam VARCHAR(10),#可变必须指定长度 salary DOUBLE(10,2), hire_date DATE ); SELECT * FROM aaa.myemp;
#增
#方式一,一条一条添加数据
#默认状况下,须要按照表中的列的顺序依次赋值
INSERT INTO myemp VALUES(1,'tom1',3400,NOW());
#默认循序按列的排列顺序来的
INSERT INTO myemp VALUES(1,'tom1',NOW(),3400);
#这样写测试经过,不过没意义
#开发中常见状况
#有时候,不太清楚先哪一个列后哪一个列
#就能够在表后指定顺序,这种方法在程序开发里用的比较多
INSERT INTO myemp(id,nam,hire_date,salary) #显示的列出表中的列,通常都这样作 VALUES(1,'tom1',NOW(),3600);
#假如员工工资还没定下来,因此能够填null
INSERT INTO myemp(id,nam,hire_date,salary) VALUES(1,'tom1',NOW(),NULL);
#表有四个列,参数表中只写了三个,
#则下边的具体参数也要写三个
#这种状况用的也比较多,剩余列自动填null
INSERT INTO myemp(id,nam,hire_date) VALUES(1,'tom1',NOW());
#用户信息,填表可能不完整,在保存时没写的自动填NULL
#没有声明添加数据的列,数据默认为nulll,在开发中很常见
#有时会执行不成功,涉及到约束问题
#salary添加过非空约束的话,那么执行时就会报错
#有些非空的列,必需要赋值,
#以上是一条一条添加
#方式二,导入数据,基于现有的表
#导入时要注意列的类型和范围是否同样
DESC myemp;#导表示先看结构 DESC emp; CREATE TABLE hehehe AS SELECT * FROM myemp; INSERT INTO hehehe(id,nam,salary) SELECT id,nam,salary FROM myemp; #where.....
#删除数据 : delete from
DELETE FROM myemp WHERE salary IS NULL;#删除空行
#写的时候一般有过滤条件,不然全删除了
#delete from 是自然的批量操做
#删除,有时会删除失败(报错)
#表不存在
#约束,主要对列加约束
#外键约束
#A表有一个地区编号,B表也有一个地区编号
#AB表关联之后,若是再向A表的地区编号写一个
#另外的值,这个值在b表的地区编号中不存在
#那么会报错,违反外键约束
#外键约束的值不能删
#删父表的数据,先去子表查一下看有没有相关关联
#由于有外键约束,且在employees 找到了对应的90号部门相关的员工数据,因此删除失败
DELETE FROM departments WHERE department_id=90;
#修改数据 update … set …where…
UPDATE myemp SET salary=12000 WHERE id=1;
#此操做也是批量操做,若是不指定where条件,则所有更新
UPDATE myemp SET salary=12000,id=222,hire_date='1999-09-09' WHERE id=2;
#有外键约束的时候也要谨慎删除
#删除的特色
#级联删除,级联置空 (看课件)
#多表同步的意思
#在设置外键约束时,在后边加上一些条件。。。。
#数据库事务 一条或多条的DML的操做综合在一块儿
#叫数据库事务
#数据库事务:一条或多条DML操做组合在一块儿,构成数据库事务
#AA 转帐 给BB
#转帐的一个同步性,我转你收,你收不到,就回滚
#update emp set salary=salary-100 where name='AA' #update emp set salary=salary+100 where name='BB'
#处理事务的原则:要么一个事务中的多个DML操做都执行成功,此时提交数据
#将修改了的数据保存下来
#要么都执行不成功,则已经执行了的操做也要回滚回去。
#CC向DD转帐100
#又构成一个事务,总体出现,要么都出现,要么都不出现
#DML操做,支持数据的回滚操做。
#DDL操做,不支持数据的回滚,删除一个表,修改一个表,都不能够回滚
SET autocommit=FALSE;#设置为不自动提交操做
#开发中,先让autocommit变量为false
#try{ #update emp set salary=salary-100 where name='AA' #update emp set salary=salary+100 where name='BB' #commit; #} catch(){ #rollback; #} #java 中相似这么表示
#commit;
commit; SET autocommit=FALSE; SELECT * FROM goods; DELETE FROM goods; ROLLBACK;
_____________________________________________________________________________________
#约束(constraint) 关键字
#为了保证数据一致性和完整性,SQL规范以约束的方式对表数据尽心额外的条件限制
#常见的约束:费控约束(not null) 惟一性约束(unique) 主键约束(primaary key) 外键约束(foreign key)
#检查性约束(check) 默认值约束(default)
#如何给表添加约束:1建立的同时添加约束,2经过修改表的方式,添加,删除约束,约束不能说是修改(先删 再加)
#在一开始考虑到,造表的时候考虑清楚,不然后期可能出现约束添加不上,删除不了的状况
#添加方式的体现:1 列级约束 2 表级约束(写在表的后边而已)
#约束其实是对表的列的限制,对表中数据额外加的限制
#通俗来讲就是对表中列在进行DML操做时的限制
#1.非空约束(not null)
#只能使用列级约束
USE aaa; CREATE TABLE myem1( id INT NOT NULL , NAME VARCHAR(15) NOT NULL, salary DOUBLE (10,2) );
DESC myem1; INSERT INTO myem1(id,NAME,salary) VALUES(1,'tom',200);
#报错 Field ‘id’ doesn’t have a default value
#添加失败
INSERT INTO myem1(NAME,salary) VALUES('t1',200); INSERT INTO myem1(NAME,salary) VALUES(200);
#最后一个字段能够为空,由于没有非空限制
INSERT INTO myem1(id,NAME,salary) VALUES(1,'tom',NULL);
#删除非空约束
ALTER TABLE myem1 MODIFY NAME VARCHAR(15) NULL; DESC myem1;
#添加非空约束
#有可能执行不成功,(缘由:若是现有的salary中已有null值,则添加约束失败)
ALTER TABLE myem1 MODIFY salary DOUBLE(10,2) NOT NULL;
#2.惟一性约束 (unique)
#列值是惟一的
USE aaa; CREATE TABLE myem2( id INT UNIQUE, #列级约束,这默认起约束名 NAME VARCHAR(15), email VARCHAR(20), hire_date DATE, #表级约束 约束名 CONSTRAINT emp2_id_uk UNIQUE(email), CONSTRAINT emp2_hire_date_uk UNIQUE(hire_date) );
#NULL能够出现屡次,不认为是同样的数据
#能够向声明为unique的列上屡次添加null
INSERT INTO myem2(id,NAME,hire_date) VALUES(3,'tom','2019-09-10');
#重复添加会添加失败
INSERT INTO myem2(id,NAME,hire_date,email) VALUES(31,'t11om','2019-1-10','178@qq,com');
#删除惟一性约束
#系统会自动向声明为惟一性约束的列上添加索引
ALTER TABLE myem2 DROP INDEX emp2_hire_date_uk;
#删掉索引,对应的惟一性约束也就删掉了。
#添加惟一性约束
#…
#3.主键约束(primary key)
#主键的约束做用的列要求:非空且惟一
#一个表中,只能声明一个主键约束
#使用做用有主键约束的列做为查询条件,能够定位表中的惟一的一条记录
#惟一约束有null值的状况
CREATE TABLE my3( id INT PRIMARY KEY, NAME VARCHAR(15) CONSTRAINT my3_id_pk PRIMARY KEY(id) );
CREATE TABLE my3( id INT AUTO_INCREMENT,#一般使用自增加,自动维护 NAME VARCHAR(15), CONSTRAINT my3_id_pk PRIMARY KEY(id) );
INSERT INTO my3(NAME)#由于设置了主键自增加,因此这里能够只写一个name VALUES('张三'); INSERT INTO my3(NAME)#由于设置了主键自增加,因此这里能够只写一个name VALUES('李四');
SELECT * FROM my3;
#4.外键约束:一样做用在列上
CREATE TABLE m1( dept_id INT, dept_name VARCHAR(10) ); INSERT INTO m1(dept_id,dept_name) VALUES(10,'it'); INSERT INTO m1(dept_id,dept_name) VALUES(20,'Account'); #须要先为mi添加主键或惟一约束 ALTER TABLE m1 ADD CONSTRAINT dept_id_pk PRIMARY KEY(dept_id); DELETE FROM m2; ROLLBACK; CREATE TABLE m2( id INT, NAME VARCHAR(15), dept_id INT, #外键约束(关联到的mydept的dept_id须要有惟一性的约束或主键约束) CONSTRAINT m2_dept_id_fk FOREIGN KEY(dept_id) REFERENCES m1(dept_id)#在这个地方添加级联删除,级联置空的约束 #意思。。 );
#要求向m2 表中dept_id添加值时,要求值必须是m1表中dept_id出现过的值
#正确的
INSERT INTO m2(id,NAME,dept_id) VALUES(2,'TOM',10);
#错误的
INSERT INTO m2(id,NAME,dept_id) VALUES(1,'TOM',40);
#5.检查约束 check 对oracle有效,对mysql失效了
#sql语言里有这个规范,mysql里写和没写同样 CREATE TABLE m3( id INT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(10), salary DOUBLE(10,2) CHECK(salary>3000) );
#mysql执行仍然成功,oracle报错
INSERT INTO m3(NAME,salary) VALUES('tom',100);#加入check无心义,照样执行
#6.默认值约束(default)
CREATE TABLE m4( id INT, NAME VARCHAR(15), salary DOUBLE(10,2) DEFAULT 3000 ); INSERT INTO m4(id,NAME) VALUE(1,'tom'); SELECT * FROM m4;
#分页
#要查的数据比较多
SELECT * FROM goods LIMIT 0,10;#查询前十条数据
#查询goods_number 前十的信息
SELECT * FROM goods ORDER BY goods_number DESC
#LIMIT 0,10;#查询前十条数据
#第一个参数表示从多少条开始,第二个参数表示显示多少条
#在查询中limit写在order by的后边
LIMIT 20,3; #查询20-23的数据
#写成公式,显示第pagenumber页的pagesize条数据
#limit (pagenumber-1)*pagesize,pagesize
#约束比较多 主要掌握,主键约束,造表是主键都会加上
(本笔记整理自网络资源,侵删)