mysql 表字段信息从一张表迁移到另一张表_MySQL(数据库)笔记
###數據庫
之前通過流去操作文件保存數據庫的弊端:
1.執行效率低
2.開發成本高
3.一般只能保存小量數據
4.只能保存文本數據
####什么是DB
- DataBase 數據庫:代表文件集合
####什么是DBMS
- DataBaseManagementSystem 數據庫管理系統(軟件),用于管理保存數據的文件集合,用于和程序員進行交互,常
見的DBMS有:Oracle MySQL DB2 SQLServer Sqlite
####SQL
- Structured Query Language:結構化查詢語言,用戶程序員和DBMS進行交互,用于程序員告訴DBMS到底對數據進
行什么操作的
###數據庫的分類(了解)
- 關系型數據庫:經過數據理論驗證可以將現實生活中的各種關系保存到數據庫,這種就稱為關系型數據庫.保存數據以表為單位
- 非關系數據庫:一般都是為了解決特定場景的問題 比如:緩存,高并發訪問,Redis數據庫(以key-value形式保存數據)
###常見的關系數據庫
- MySQL:屬于Oracle公司的產品,
- Oracle:
- DB2:
- SQLServer:
- Sqlite:
###打開客戶端鏈接MySQL
- 在終端中執行:mysql -uroot -p 回車 如果有密碼寫密碼 回車,如果沒有密碼則直接回車
###和數據庫相關的SQL
###查詢所有的數據庫
show databases;
###創建數據庫
create database db1;
###查看數據庫詳情
show create database db1;
###創建數據庫指定字符集
create database db2 character set gbk/utf8;
###刪除數據庫
drop database db2;
###和表相關的SQL
###查詢所有表
- show tables;
###創建表
- create table 表名(字段1名 字段1的類型,字段2名 字段2的類型,...);
create table person(name varchar(10),age int);
###查看表詳情
- show create table 表名;
###常見表時指定表的引擎和字符集
- create table t1(name varchar(10)) engine=myisam charset=gbk;
###表的引擎
- innodb :支持數據庫的高級操作 如:外鍵,事務等,默認引擎
- myisam:只支持基礎的增刪改查操作
###SQL格式:
1.可以有換行
2.最后以";"結尾
3.關鍵字之間需要有空格(可以寫多個空格,建議寫一個)
###查看表字段
- desc 表名;
###刪除表
- drop table 表名;
###修改相關表
1.修改表名
rename table 原名 to 新名;
rename table student to stu;
2.修改表的引擎和字符集
- alter table 表名 engine=myisam/innodb charset=utf8/gbk;
alter table stu engine=myisam charset=gbk;
3.添加表字段
- 最后面添加:alter table 表名 add 字段名 字段類型;
- 最前面添加:alter table 表名 add 字段名 字段類型 first;
- xxx的后面添加:alter table 表名 add 字段名 字段類型 after xxx;
create table hero(name varchar(10));
alter table hero add age int;
alter table hero add id int first;
alter table hero add sal int after name;
4.刪除表字段
- alter table 表名 drop 字段名;
alter table hero drop sal;
5.修改表字段的名字和類型
- alter table 表名 change 原字段名 新字段名 新字段類型;
alter table hero change name heroname varchar(10);
6.修改表字段的類型和位置
- alter table 表名 modify 字段名 類型 位置;
alter table hero modify age int first(after xxx);
###數據相關
####插入數據
create table emp(id int,name varchar(10),age int,sal int);
-全表插入數據:
- insert into emp values(1,'tom',18,3000);
-指定字段插入數據:
- insert into emp (name,age ) values('terry',19);
- insert into emp (name ) values('李白');
-批量插入數據:
- insert into emp values(3,'劉備',28,6000),(4,'張飛',20,5000),(5,'關羽',25,9000);
- insert into emp (name,age) values('悟空',500),('八戒',400),('沙僧',300);
###查詢數據
-查詢全部數據的全部字段信息
select * from emp;
-查詢所有員工的姓名和年齡
select name,age from emp;
-查詢年齡在25歲一下的員工信息
select * from emp where age<25;
-查詢工資3000塊錢的員工姓名,年齡,工資
select name,age,sal from emp where sal=3000;
####修改數據
-修改Tom的工資為3333
update emp set sal=3333 where name='tom';
-修改30歲一下的工資為6666
update emp set sal=6666 where age<30;
-修改id等于3的名字為呂布 年齡為55 工資為20000
update emp set name='呂布',age=55,sal=20000 where id=3;
-修改工資為null的工資為800
update emp set sal=800 where sal=null;
####刪除數據
-刪除id等于1的員工
delete from emp where id=1;
-刪除年齡在25歲以下的員工
delete from emp where age<25;
-刪除全部數據
delete from emp;
###主鍵約束
- 主鍵:用于表示數據唯一性的字段稱為主鍵
- 約束:是給表字段添加的限制條件
- 主鍵約束:限制主鍵字段值不能重復并且非空(唯一且非空)
create table t1(id int primary key,name varchar(10));
insert into t1 values(1,'Tom');
insert into t1 values(1,'jerry');//失敗,重復
insert into t1 values(null,'ABC')//失敗,不能為null
- 自增: auto_increment
create table t2(id int primary key auto_increment,name varchar(10));
insert into t2 values(null,'AAA');//
insert into t2 values(2,'AAA');
insert into t2 values(10,'mm');
insert intp t2 values(null,'AAA');
1.當字段值為null的時候值會自己增長
2.自增字段值也可以手動賦值
3.增長規則:從曾經出現過的最大值基礎上+1
4.自增數值只增不減(delete清空表,自增數值并不清零)
###注釋 comment
- 創建表聲明字段的時候給字段添加的介紹
create table t3(id int primary key auto_increment comment '這是一個主鍵', name varchar(10) comment '這是員工的姓名');
###`和'
- `:用于修飾表名和字段名 可以省略
create table `t4`(`id` int,`name` varchar(10));
- ':用于修飾字符串
###數據冗余
- 如果表設計不夠合理,保存大量數據的同時可能隨之會出現大量重復數據,這些重復數據的現象就稱為數據冗余,通過拆分表的形式解決冗余問題
###事務
- 什么是事務:事務是數據庫中執行SQL語句的最小執行單位,可以保證事務內的多條SQL語句要么全部成功,要么全部失敗.
- 查看數據庫自動提交的狀態
show variables like '%autocommit%';
- 關掉自動提交 0關閉 1開啟
set autocommit=0;
pollk-測試轉賬:
create table person(id int,name varchar(10),money int);
inert into person values(1,'超人',500),(2,'鋼鐵俠',10000);
-關掉自動提交: set autocommit=0;
1.先讓超人+2000;
update person set money=2500 where id=1;
2.開啟另一個終端 驗證 此時數據庫文件的數據并沒有改掉
3.讓鋼鐵俠-2000
update person set money=8000 where id=2;
4.執行提交
commit;
-回滾 rollback;
-將內存的修改回滾到上次提交的點
update person set money=100 where id=1;
rollback;
保存回滾點 savepoint
update person set money=100 where id=1;
savepoint s1;
update person set money=200 where id=1;
savepoint s2;
rollback to s1;
###SQL的分類
####DDL Data Definition Language
- 數據定義語言,包括 create,alter,drop,truncate ,不支持事務
####DML Data Manipulation Language
- 數據操作語言, 包括 insert,delete,update,select(DQL),支持事務
####DQL Data Query Language
- 數據查詢語言,只包括select,和事務沒有關系因為并沒有修改數據
####TCL Transaction Control Language
- 事務控制語言,包括 commit,rollback, savepoint,rollback to
####DCL Data Control Language
- 數據控制語言,用于處理分配用戶權限相關的操作
###truncate
- truncate table 表名;
- 刪除表并且創建一個新表
- truncate、drop和delete的區別:
- delete用于刪除數據,使用delete清空表時自增數值不清零 執行效率最低
- drop 用于刪除表 執行效率最高
- truncate 用于刪除表并創建新的空表,執行效率比delete要高,而且自增數值會清零
###數據庫的數據類型
####整數
- 常用整數有 int(m)和bigint(m),m代表顯示長度必須和zerofill結合使用
create table t_int(num int(10) zerofill);
insert into t_int values(123);
select * from t_int;
####浮點數
- 常用浮點數double(m,d) m代表總長度 d代表小數長度 23.346 m=5 d=3
- decimal超高精度浮點數,應用場景:涉及超高精度運算時使用
create table t_double(num double(5,3));
insert into t_double values(23.5678); 值為23.568
insert into t_double values(23.5); 值為23.500
####字符串
- char(m): 固定長度 m=10 abc 占10,效率高,最大255
- varchar(m):可變長度 m=10 abc 占3,節省空間,最大65535,如果超過255建議使用text
- text(m):可變長度 最大65535
####日期
- date:只能保存年月日
- time:只能保存時分秒
- datetime:保存年月日時分秒,默認值為null,最大值9999-12-31
- timestamp(時間戳距離19700101 08:00:00):保存年月日時分秒,默認值為當前系統時間,最大值2038-01-19
create table t_time(t1 date,t2 time,t3 datetime,t4 timestamp);
insert into t_time values('2018-10-16',null,null,null);
insert into t_time values
(null,'20:06:32','2008-11-22 18:22:11',null);
配置URL:
jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=UTF-8
三方SQL工具:sqlyog
###is null和is not null
1.查詢emp表中沒有上級領導mgr的員工編號empno,姓名ename,工資sal
select empno ,ename,sal from emp where mgr is null;
2.查詢emp表中沒有獎金comm的員工姓名,工資,獎金
select ename,sal,comm from emp where comm is null;
3.查詢有獎金的所有員工信息
select * from emp where comm is not null;
###別名
1.將查詢到的員工姓名enamel改為'姓名'
select ename from emp;
select ename as '姓名' from emp;
select ename '姓名' from emp;
select ename 姓名,sal 工資 from emp;
###去重distinct
1.查詢emp表中出現的所有職位job
select distinct job from emp;
###比較運算符 >,<,>=,<=,=,!=和<>
1.查詢工資小于1600的所有員工的姓名和工資
select ename ,sal from emp where sal<1600;
2.查詢部門編號是20的所有員工姓名,職位和部門編號deptno
select ename,job,deptno from emp where deptno=20;
3.查詢職位是manager的所有員工姓名和職位
select ename,job from emp where job='manager';
4.查詢部門不是10號部門的所有員工姓名和部門編號(兩種方法)
select ename,deptno from emp where deptno<10 or deptno>10;
select ename,deptno from emp where deptno!=10;
5.查詢商品表t_item中單價price等于23的商品信息
select * from t_item where price=23;
6.查詢商品表中單價不等于8443的商品信息
select * from t_item where price!=8443;
###and 和 or
- and 等效于java中的&&
- or 等效于java中的||
- 查詢工資大于2000并且是10號部門的員工信息
select * from emp where sal>2000 and deptno=10;
1.查詢不是10號部門并且工資大于等于1600的員工姓名,工資,部門編號
select ename,sal,deptno from emp where deptno!=10 and sal>=1600;
2.查詢部門是30號部門或者上級領導為7698的員工姓名,職位,上級領導和部門編號
select ename,job,mgr,deptno from emp where deptno=30 or mgr=7698;
3.查詢有上級領導并且工資低于2000,并且是20號部門的員工信息
select * from emp where mgr is not null and sal<2000 and deptno=20;
###in
1.查詢emp表中工資是5000,1500,3000的員工信息
select * from emp where sal=5000 or sal=1500 or sal=3000;
select * from emp where sal in(5000,1500,3000);
###between x and y
1.查詢工資在2000到3000之間的員工姓名和工資
select ename,sal from emp where sal>2000 and sal<3000;
select ename,sal from emp where sal between 2000 and 3000;
###模糊查詢 like
- _ :代表單個未知字符
- % :代表0或多個未知字符
- 舉例:
1.以a開頭的字符串: a%
2.以m結尾 %m
3.包含x %x%
4.第二個字符是a _a%
5.倒數第三個字母是m %m__
6.以a開頭并且倒數第二個字母是b a%b_
-案例:
1.查詢名字中包含a的所有員工姓名和工資:
select ename,sal from emp where ename like '%a%';
2.查詢標題中包含記事本的商品標題及商品價格
select title,price from t_item where title like '%記事本%';
3.查詢單價低于100的記事本(title包含記事本)
select title from t_item where price<100 and title like '%記事本%';
4.查詢單價在50到200之間的得力商品(title包含得力)
select title from t_item where price between 50 and 200 and title like '%得力%';
5.查詢商品分類為238和917的商品信息
select * from t_item where category_id=238 or category_id=917;
6.查詢有贈品的商品信息(賣點sell_point中包含贈字)
select * from t_item where sell_point like '%贈%';
7.查詢有圖片的image的得力商品信息
select * from t_item where image is not null and title like '%得力%';
8.查詢和得力無關的商品信息(title不包含得力)
select * from t_item where title not like '%得力%';
9.查詢價格在50到100以外的商品信息
select * from t_item where price<50 or price>100;
###排序 order by
- order by 關鍵字,by 后面寫排序的字段名稱 默認是升序
- asc 升序 , desc 降序
1.查詢所有員工的姓名和工資按照工資升序排列
select ename,sal from emp order by sal ;
2.查詢10號部門的所有員工信息,按照工資降序排列
select * from emp where deptno=10 order by sal desc ;
3.查詢所有帶燃字的商品,按照價格升序排列
select * from t_item where title like '%燃%' order by price ;
4.查詢所有dell商品按照分類category_id升序排列
select * from t_item where title like '%dell%' order by category_id ;
5.查詢所有員工按照部門升序排列 如果部門一致則按照工資降序排列
select * from emp order by deptno asc , sal desc;
6.查詢所有商品分類和單價按照分類降序排列,如果分類相同則按照價格升序排列
select category_id,price from t_item order by category_id desc ,price;
###分頁查詢 limit
- limit 跳過的條數,請求的數量(每頁的數量)
limit 0,10;
limit 10,10;
第五頁的20條
limit (5-1)*20,20;
第八頁的4條數據
limit (8-1)*4,4;
1.查詢員工表中的工資降序的前5條
select * from emp order by sal desc limit 0,5;
2.查詢員工表中工資降序的第3頁的4條數據
select * from emp order by sal desc limit 8,4;
3.查詢商品表中價格升序的前10條數據
select * from t_item order by price limit 0,10;
4.查詢商品表中價格低于100元的商品信息第三頁的三條數據
select * from t_item where price<100 order by price limit 6,3;
5.查詢10號部門和30號部門的員工工資在前三名的員工信息
select * from emp where deptno=10 or deptno=30 order by sal desc limit 0,3;
###concat() 函數
- 把concat內部的參數拼接到一起
1.查詢員工姓名和工資,要求工資單位是元
select ename,concat(sal,'元') 工資 from emp;
###數值計算 + - * / % (mod(7,2)等效于 7%2)
1.查詢商品表中每個商品的單價,庫存及總價值(單位*庫存)
select price,num,price*num from t_item;
2.查詢員工表中每個員工的姓名,工資以及年終獎(五個月的工資)
select ename,sal,sal*5 年終獎 from emp;
###日期相關函數
1.獲取當前的年月日時分秒
select new();
2.獲取當前的日期 current
select curdate();
3.獲取當前的時間
select curtime();
4.從年月日時分秒中提取年月日
select date(new());
5.從年月日時分秒提取時分秒
select time(new());
6.從年月日時分秒提取時間分量 年 月 日 時 分 秒
-extract(year from now())
-extract(month from now())
-extract(day from now())
-extract(hour from now())
-extract(minute from now())
-extract(second from now())
select extract(year from now());
-查詢員工表中的所有員工姓名和入職的年份
select ename,extract(year from hiredate) from emp;
7.日期格式化 date_format(時間,格式)
now() 2018年12月31日 18:23:15
-%Y:四位年 2018
-%y:兩位年 18
-%m:兩位月 05
-%c:一位月 5
-%d:日
-%H:24小時
-%h:12小時
-%i:分
-%s:秒
select date_format(now(),'%Y年%m月%d日 %H時%i分%s秒');
查詢商品名稱和商品上傳日期(格式:x年x月x日)
select title, DATE_FORMAT(created_time,'%Y年%m月%d日') 日期 from t_item;
-8把非標準的日期字符串轉成標準的時間格式 str_to_date(時間字符串,格式)
14.08.2018 08:00:00
select str_to_date('14.08.2018 08:00:00','%d.%m.%Y %H:%i:%s') 標準化日期;
###ifnull(x,y)函數
-age-ifnull(x,18) 如果x的值為null 則age=18 如果不為null則age=x
1.修改員工表中獎金為null的值為0
update emp set comm=ifnull(comm,0);
###聚合函數
-用于對多條數據進行統計
1.求和 sum(字段名)
-查詢emp中10號部門的工資總和
select sum(sal) 工資總和 from emp where deptno=10;
2.平均值 avg(字段名)
-查詢emp表中所有員工工資的平均值
select avg(sal) 平均工資 from emp;
-查詢30號部門的員工的最高獎金
select max(comm) 最高獎金 from emp where deptno=30;
4.最小值 min(字段名)
-查詢商品表中價格最便宜的商品的單價
select min(price) 最低價格 from t_item ;
5.統計數量 count(字段名) 一般使用count(*)
3.最大值 max(字段名)
###聚合函數練習:
1.統計工資在2500以上的員工人數
select count(*) from emp where sal>2500;
2.查詢工資在1000到3000以內的最大獎金
-統計30號部門有多少人
select count(*) from emp where deptno=30;
select max(comm) from emp where sal in(1000,3000);
3.查詢30號部門的最大獎金,最高工資,工資平均值,工資總和,并對查詢結果起別名
select max(comm) 最大獎金,max(sal) 最高工資,avg(sal) 平均工資,sum(sal) 工資總和 from emp where deptno=30;
4.查詢價格在100元以內的商品數量
select count(*) from t_item where price<100;
5.查詢名字包含a的員工數量
select count(*) from emp where ename like '%a%';
####和字符串相關函數
1.獲取字符串的長度 char_length(str);
獲取所有員工的姓名和姓名的字符長度
select ename,char_length(ename) from emp;
2.獲取字符串在另一個字符串中出現的位置 instr(str,substr)
select insert('abdcefg','d');
3.插入字符串 insert(str,start,length,newStr)
select insert('abcdefg',3,2,'m');//abmefg
4.轉大寫,轉小寫
select upper('abc'),lower('NBA');
5.左邊截取和右邊截取
select left('abcdefg',2),right('abcdefg',2);
6.去兩端空白
select trim(' a b ');
7. 截取字符串
select substring('abcdefg',3,2);
8. 重復 repeat(str,count)
select repeat('ab',2);
9. 替換 replace(str,old,new)
select replace('This is mysql','my','your');
10. 反轉 reverse(str)
select reverse('abc');
###回顧:
1. is null 和 is not null
2. 別名
3. 去重 distinct
4. and 和 or
5. 比較運算符 > < >= <= = !=和<>
6. in
7. between x and y
8. like _單個未知 %0或多個未知
9. order by age asc/desc,sal
10. limit 12,3
11. concat(abc,mm)
12. 數值運算 + - * / %和 mod()
13. 日期 now() curdate() curtime() date(now()) time(now()) extract(year/month/day/hour/minute/second from now()) date_format(now(),'格式') Y y m c d H h i s , str_to_date(時間字符串,格式)
14. age=ifnull(x,y) 如果x=null age=y x!=null age=x
15. 聚合函數 sum() avg() max() min() count(*)
16. 字符串 char_length instr insert upper lower left right substring replace repeat reverse trim
###作業:
1.案例:查詢沒有上級領導的員工的編號,姓名,工資
select empno,ename,sal from emp where mgr is null;
2.案例:查詢emp表中沒有獎金的員工的姓名,職位,工資,以及獎金
select enamem,job,sal,comm from emp where comm is null;
3.案例:查詢emp表中含有獎金的員工的編號,姓名,職位,以及獎金
select empno ,ename,job,comm from emp where comm is not null;
4.案例:查詢含有上級領導的員工的姓名,工資以及上級領導的編號
select ename,sal,mgr from emp where comm is not null;
5.案例:查詢emp表中名字以‘S’開頭的所有員工的姓名
select ename from emp where ename like 's%';
6.案例:查詢emp表中名字的最后一個字符是'S'的員工的姓名
select ename from emp where ename like '%s';
7.案例:查詢倒數的第2個字符是‘E’的員工的姓名
select ename from emp where ename like '%E_';
8.案例:查詢emp表中員工的倒數第3個字符是‘N’的員工姓名
select ename from emp where ename like '%N__';
9.案例:查詢emp表中員工的名字中包含‘A’的員工的姓名
select ename from emp where ename like '%A%';
10.案例:查詢emp表中名字不是以'K'開頭的員工的所有信息
select * from emp where ename not like 'K%';
11.案例:查詢emp表中名字中不包含‘A’的所有員工的信息
select * from emp where ename not like '%A%';
12.案例:做文員的員工人數(job 中 含有 CLERK 的)
select count(job) from emp where job like '%CLERK%';
13.案例:銷售人員 job: SALESMAN 的最高薪水
select max(sal) from emp where job='SALESMAN';
14.案例:最早和最晚入職時間
select min(HIREdate) 最早入職時間,max(HIREdate) 最晚入職時間 from emp;
15.案例:查詢類別 163的商品總庫存量
select sum(num) 總庫存量 from t_item where category_id=163;
16.案例:查詢 類別 163 的商品
select * from t_item where category_id=163;
17.案例:查詢商品價格不大于100的商品名稱列表
select title from t_item where price<=100;
18.案例:查詢品牌是聯想,且價格在40000以上的商品名稱和價格
select title,price from t_item where title like '&聯想&' and price>40000;
19.案例:查詢品牌是三木,或價格在50以下的商品名稱和價格
select title,price from t_item where title like '%三木%' or price<50;
20.案例:查詢品牌是三木、廣博、齊心的商品名稱和價格
select title,price from t_item where title like '%三木%' or title like '%廣博%' or title like '%齊心%';
21.案例:查詢品牌不是聯想、戴爾的商品名稱和價格
select title,price from t_item where title not like '%聯想%' and title not like '%戴爾%';
22.案例:查找品牌是聯想且價格大于10000的電腦名稱
select title from t_item where title like '%聯想%' and price>10000;
23.案例:查詢聯想或戴爾的電腦名稱列表
select title from t_item where title like '%聯想%' or title like '%戴爾%';
24.案例:查詢聯想、戴爾、三木的商品名稱列表
select title from t_item where title like '%聯想%' or title like '%戴爾%' or title like '%三木%';
25.案例:查詢不是戴爾的電腦名稱列表
select title from t_item where title not like '%戴爾%';
26.案例:查詢所有是記事本的商品品牌、名稱和價格
select title,item_type,price from t_item where title like '%記事本%';
27.案例:查詢品牌是末尾字符是'力'的商品的品牌、名稱和價格
select title,item_type,price from t_item where title like '%力(%' or title like '%力(%';
28.案例:名稱中有聯想字樣的商品名稱
select title from t_item where title like '%聯想%';
29.案例:查詢賣點含有'贈'產品名稱
select title from t_item where sell_point like '%贈%';
30.案例:查詢emp表中員工的編號,姓名,職位,工資,并且工資在1000~2000之間。
select empno,ename,job,sal from emp where sal>=1000 and sal<=2000;
31.案例:查詢emp表中員工在10號部門,并且含有上級領導的員工的姓名,職位,上級領導編號以及所屬部門的編號
select ename,job,mgr,deptno from emp where deptno=10 and mgr is not null;
32.案例:查詢emp表中名字中包含'E',并且職位不是MANAGER的員工的編號,姓名,職位,以及工資。
select empno,ename,job,sal from emp where ename like '%E%' and job!='MANAGER';
33.案例:查詢emp表中10號部門或者20號部門中員工的編號,姓名,所屬部門的編號
select empno,ename,deptno from emp where deptno=10 or deptno=20;
34.案例:查詢emp表中沒有獎金或者名字的倒數第2個字母不是T的員工的編號,姓名,職位以及獎金
select empno,ename,job,comm from emp where comm is null or ename not like '%T_';
35.案例:查詢工資高于3000或者部門編號是30的員工的姓名,職位,工資,入職時間以及所屬部門的編號
select ename,job,sal,hiredate,deptno from emp where sal>3000 or deptno=30;
36.案例:查詢不是30號部門的員工的所有信息
select * from emp where deptno!=30;
37.案例:查詢獎金不為空的員工的所有信息
select * from emp where comm is not null;
38.案例:查詢emp表中所有員工的編號,姓名,職位,根據員工的編號進行降序排列
select empno,ename,job from emp order by empno desc;
39.案例:查詢emp表中部門編號是10號或者30號中,所有員工姓名,職務,工資,根據工資進行升序排列
select ename,job,sal from emp where deptno=10 or deptno=30 order by sal;
40.案例:查詢emp表中所有的數據,然后根據部門的編號進行升序排列,如果部門編號一致,根據員工的編號進行降序排列
select * from emp order by deptno ,empno desc;
41.案例:查詢emp表中工資高于1000或者沒有上級領導的員工的編號,姓名,工資,所屬部門的編號,以及上級領導的編號,根據部門編號進行降序排列,如果部門編號一致根據工資進行升序排列。
select empno,ename,sal,deptno,mgr from emp where sal>1000 or mgr is null order by deptno desc,sal ;
42.案例:查詢emp表中名字中不包含S的員工的編號,姓名,工資,獎金,根據工資進行升序排列,如果工資一致,根據編號進行降序排列
select empno,ename,sal,comm from emp where ename not like '%S%' order by sal ,empno desc;
43.案例:統計emp表中員工的總數量
select count(*) from emp;
44.案例:統計emp表中獲得獎金的員工的數量
select count(comm) from emp;
45.案例:求出emp表中所有的工資累加之和
select sum(sal) from emp;
46.案例:求出emp表中所有的獎金累加之和
select sum(comm) from emp;
47.案例:求出emp表中員工的平均工資
select avg(sal) from emp;
48.案例:求出emp表中員工的平均獎金
select avg(comm) from emp;
49.案例:求出emp表中員工的最高工資
select max(sal) from emp;
50.案例:求出emp表中員工編號的最大值
select max(empno) from emp;
51.案例:查詢emp表中員工的最低工資。
select min(sal) from emp;
52.案例:查詢emp表中員工的人數,工資的總和,平均工資,獎金的最大值,獎金的最小值,并且對返回的列起別名。
select count(*) 總人數,sum(sal) 工資總和,avg(sal) 平均工資,max(comm) 獎金最大值,min(comm) 獎金最小值 from emp;
53.案例:查詢emp表中每個部門的編號,人數,工資總和,最后根據人數進行升序排列,如果人數一致,根據工資總和降序排列。
select deptno,count(*) 人數,sum(sal) 工資總和 from emp group by deptno order by 人數,工資總和 desc;
54.案例:查詢工資在1000~3000之間的員工信息,每個部門的編號,平均工資,最低工資,最高工資,根據平均工資進行升序排列。
select deptno,avg(sal) 平均工資,min(sal) 最低工資,max(sal) 最高工資 from emp where sal>=1000 and sal<=3000 group by deptno order by 平均工資;
55.案例:查詢含有上級領導的員工,每個職業的人數,工資的總和,平均工資,最低工資,最后根據人數進行降序排列,如果人數一致,根據平均工資進行升序排列
select count(job) 每個職業人數,sum(sal) 工資總和,avg(sal) 平均工資,min(sal) 最低工資 from emp where mgr is not null group by job order by 每個職業人數 desc,平均工資;
56.案例:查詢工資在1000~3000之間每一個員工的編號,姓名,職位,工資
select empno,ename,job,sal from emp where sal between 1000 and 3000;
57.案例:查詢emp表中獎金在500~2000之間所有員工的編號,姓名,工資以及獎金
select empno,ename,sal,comm from emp where comm between 500 and 2000;
58.案例:查詢員工的編號是7369,7521,
select * from emp where empno=7369 or empno=7521;
59.案例:查詢emp表中,職位是ANALYST,
select * from emp where job='ANALYST';
60.案例:查詢emp表中職位不是ANALYST,
select * from emp where job!='ANALYST';
###數學相關函數
1.向下取整 floor(num)
select floor(3.84);
2.四舍五入 round(num)
select round(3.84);
-round(num,m) m代表小數位數
select round(3.1415936,3);//3.142
3.非四舍五入 truncate(num,m)
select truncate(3.1415926,3);//3.141
4.隨機數 rand(); 0-1 5-10 0-5;
select floor(rand()*6)+5;//5-10
select floor(rand()*6)+3;//3-8
###分組查詢
-分組查詢通常和聚合函數結合使用,以組為單位進行統計
-一般情況下,題目中每個xxx就在group by 后面寫xxx
1.查詢每個部門的最高工資
select max(sal) from emp group by dep tno;
2.查詢每個部門的平均工資
select avg(sal) from emp group by deptno;
3.查詢每個分類下商品的最低價格
select min(price) from t_item group by category_id;
4.查詢每個部門中工資大于1500的人數
select deptno 部門編號,count(*) 人數 from emp where sal>1500 group by deptno;
5.查詢每個領導的手下人數
select mgr 領導, count(*) 人數 from emp where mgr is not null group by mgr;
6.查詢每個商品分類的庫存數量
select category_id 商品分類,sum(num) 庫存數量 from t_item group by category_id;
--如果需要使用多個字段進行分組 直接在group by 后面寫多個字段名 通過逗號分隔
--having 后面可以寫普通字段條件也可以寫聚合函數,但是推薦在having后面只寫聚合函數
------固定的順序:select * from 表名 where .....group by xxx having ..... order by ..... limit...;
1.查詢每個部門下每個領導的手下人數
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
2.查詢每個部門的平均工資,要求平均工資大于2000
select avg(sal) a from emp group by deptno having a>2000;
3.查詢每個分類的平均單價,過濾掉平均單價低于100的
select category_id,avg(price) a from t_item group by category_id having a>=100;
####練習:
1.查詢每個分類商品的庫存總量,要求總量高于19999;
select category_id, sum(num) s from t_item group by category_id having s>19999;
2.查詢分類id為238和917的兩個分類的平均單價各是多少
select category_id, avg(price) 平均單價 from t_item where category_id=238 or category_id=917 group by category_id;
3.查詢emp表中每個部門的平均工資高于2000的部門編號,部門人數,平均工資,最后根據平均工資降序排列
select deptno,count(*) 部門人數,avg(sal) 平均工資 from emp group by deptno having 平均工資>2000 order by 平均工資 desc;
4.查詢emp表中工資在1000-3000之間的員工,每個部門的編號,工資總和,平均工資,要求過濾掉平均工資低于2000的部門,按照工資總和降序排列
select deptno,sum(sal) 工資總和,avg(sal) 平均工資 from emp where sal between 1000 and 3000 group by deptno having 平均工資>2000 order by 工資總和 desc;
5.查詢emp表中不是以s開頭每個職員的名字,人數,工資總和,最高工資,過濾掉平均工資是3000的職位,根據人數升序排序,如果一致根據工資總和降序排列
6.查詢emp表中每年入職的人數
select extract(year from hiredate) y,count(*) from emp group by y;
7.查詢emp表工資最高的員工信息
select * from emp where sal=(select max(sal) from emp);
###子查詢
1.查詢emp表工資的最高的員工信息
select max(sal) from emp;
select * from emp where sal=5000;
-子查詢
select * from emp where sal=(select max(sal) from emp);
2.查詢emp表中工資高于平均工資的員工信息
3.查詢和Jones相同工作的員工信息
select * from emp where job=(select job from emp where ename='jones') and ename!='Jones';
4.查詢工資最低的員工的所在部門同事信息
select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp)) and sal!=(select min(sal) from emp);
5.查詢最后入職的員工信息
select * from emp where hiredate=(select max(hiredate) from emp);
-having 要寫在group by 后面
6.查詢king的部門編號和部門名稱
select deptno,dname from dept where deptno=(select deptno from emp where ename='king');
7.查詢有員工的部門信息
select * from dept where deptno in(select distinct deptno from emp);
8.查詢平均工資最高的部門信息
-得到每個部門的平均工資
select deptno, avg(sal) from emp group by deptno;
-得到最高的平均工資
select deptno, avg(sal) a from emp group by deptno order by desc limit 0,1;
-通過最高的平均工資得到對應的部門編號
select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1);
-通過部門編號得到部門信息
select * from dept where deptno=(select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1));
-子查詢可以寫在什么位置
1.寫在where或having后面 當做查詢條件的值
2.寫在創建表語句的后面的時候 把查詢結果保存成一張新的表
create table emp_20 as(select * from emp where deptno=20);
3.寫在from的后面 當成一個虛擬表 **必須有別名**
select * from emp where deptno=20;
select ename,sal from (select * from emp where deptno=20) newtabte;
###關聯查詢
-同時查詢多張表的數據成為關聯查詢
1.查詢每一個員工的姓名和對應的部門名稱
select e.ename,d.ename from emp e,dept d where e.deptno=d.deptno and d.loc='new york';
2.查詢在new york工作的員工信息
select * from emp e,dept d where e.deptno=d.deptno and d.loc='new york';
3.查詢商品標題和所對應的分類名稱
select i.title,c.name from t_item i,t_item_category c where i.category_id=c.id;
###笛卡爾積
-如果關聯查詢不寫關聯關系則結果為兩張表的乘積,這個乘積稱為笛卡爾積
-笛卡爾積為一種錯誤的查詢結果,切記工作中不要出現
###等值連接和內連接
- 等值連接和內連接查詢到的內容一樣,都為兩張表中有關聯關系的數據(交集部分)
-等值連接: select * from A,B where A.x=B.x and A.age=18;
-內連接: select * from A join B on A.x=B.x where A.age=18;
1.查詢每一個員工的姓名和對應的部門名稱
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
###外連接
- 內連接和等值連接查詢到的都是交集部分的數據,外鏈接查詢到的是某一張表的全部數據+另外一張表的交集數據
-左外連接: select * from A left/right join B on A.x=B.x where A.age=18;
insert into emp (empno,ename) values(10010,'Tom');
1.查詢所有員工姓名和對應的部門名稱
select e.ename,d.dname from emp e left join dept d on e.deptno=d.deptno;
select e.ename,d.dname from emp e right join dept d on e.deptno=d.deptno;
###關聯查詢總結
- 關聯查詢的查詢方式: 等值連接 內連接和外連接
- 如果想查詢的數據為兩張表的交集數據使用等值連接或內連接(推薦)
- 如果查詢的數據是一張表的全部數據和另外一張表的交集數據則使用外連接
###作業:
1. 每個部門的人數,根據人數排序
select deptno 部門, count(*) 人數 from emp group by deptno order by 人數 desc;
2. 每個部門中,每個主管的手下人數
select deptno 部門,mgr 主管, count(*) 人數 from emp where mgr is not null group by 部門,主管;
--另一種方法:
select d.deptno,e.mgr,count(e.ename)
from emp e right join dept d
on e.deptno=d.deptno
where e.mgr is not null
group by e.mgr,d.deptno;
--查詢每個部門的人數(結果中包含40號部門)
select d.deptno,count(e.name)
from emp e right join dept d
on e.deptno=d.deptno
group by d.deptno;
3. 每種工作的平均工資
select job 職位, avg(sal) 平均工資 from emp group by 職位;
4. 每年的入職人數
select extract(year from hiredate) 年份, count(*) 人數 from emp group by 年份;
5. 少于等于3個人的部門信息
select * from dept where deptno in(select deptno from emp group by deptno having count(*)<=3);
--另一種方法:
select d.*,count(e.ename) c
from emp e right join dept d
on e.deptno=d.deptno
group by d.deptno having c<=3;
6. 拿最低工資的員工信息
select * from emp having min(sal)
7. 只有一個下屬的主管信息
select * from emp where empno in (select mgr from emp where mgr is not null group by mgr having count(*)=1);
8. 平均工資最高的部門編號
-得到最高的平均工資
select avg(sal) a from emp group by deptno order by a desc limit 0,1;
-通過平均工資值去查詢對應的部門編號
select deptno from emp group by deptno having avg(sal)=(select avg(sal) c from emp group by deptno order by c desc limit 0,1);
9. 下屬人數最多的人,查詢其個人信息
select * from emp where mgr=(select mgr from emp group by mgr having count(*)=(select count(*) c from emp group by mgr order by c desc limit 0,1));
10. 拿最低工資的人的信息
select * from emp having min(sal);
11. 最后入職的員工信息
select * from emp having max(hiredate);
12. 工資多于平均工資的員工信息
select * from emp having sal>(select avg(sal) from emp);
13. 查詢員工信息,部門名稱
select e.*,d.dname from emp e,dept d where e.deptno=d.deptno;
14. 員工信息,部門名稱,所在城市
select e.*,d.dname,d.loc from emp e,dept d where e.deptno=d.deptno;
15. DALLAS 市所有的員工信息
select e.* from emp e join dept d on e.deptno=d.deptno and d.loc='DALLAS';
16. 按城市分組,計算每個城市的員工數量
select d.loc ,count(e.ename) from emp e right join dept d on e.deptno=d.deptno group by d.loc ;
17. 查詢員工信息和他的主管姓名
select e1.*,e2.ename 主管姓名 from emp e1 join emp e2 on e1.mgr=e2.empno;
18. 員工信息,員工主管名字,部門名
select e1.*,e2.ename,d.ename from emp e1,emp e2,dept d where e1.mgr=e2.empno,e1.deptno=d.deptno;
19. 員工和他所在部門名
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
20. 案例:查詢emp表中所有員工的姓名以及該員工上級領導的編號,姓名,職位,工資
select e1.ename,e2.empno,e2.ename,e2.job,e2.sal from emp e1,emp e2 where e1.mgr=e2.empno;
21. 案例:查詢emp表中名字中沒有字母'K'的所有員工的編號,姓名,職位以及所在部門的編號,名稱,地址
select e.empno,e.ename,e.job,e.deptno,d.dname,d.loc from emp e,dept d where e.ename not like '%k%' and e.deptno=d.deptno;
22. 案例:查詢dept表中所有的部門的所有的信息,以及與之關聯的emp表中員工的編號,姓名,職位,工資
select d.*,e.empno,e.ename,e.job,e.sal from emp e LEFT join dept d on d.deptno=e.deptno;
###表設計之關聯關系
####一對一
- 什么是一對一關系: 有AB兩張表,其中A表的一條數據對應B表的一條數據,同時B表的一條數據也對應A表中的一條數據
- 應用的場景:用戶表和用戶信息擴展表
-- 用戶名 密碼 昵稱 頭像 性別 手機號 地址 郵箱....
--外鍵:表中用于建立關系的字段稱為外鍵,一張表有可能有多個外鍵,但只能有一個主鍵
-- 如何建立關系:在從表中添加外鍵指向主表的主鍵
--練習:創建表保存以下數據
用戶名wukong 密碼abcd 昵稱悟空 性別男 地址大唐
wzt admin 武則天 女 大陸
Superman 123456 超人 男 鐵嶺
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
create table userinfo(userid int,nick varchar(10),gender varchar(5), loc varchar(20));
insert into user values(null,'wukong','abcd'),(null,'wzt','admin'),(null,'superman','123456');
insert into userinfo values(1,'悟空','男','花果山'),(2,'武則天','女','大陸'),(3,'超人','男','鐵嶺');
1.查詢每個用戶對應的昵稱
select u.username,ui.nickname from user u join userinfo ui on u.id=ui.id;
2.查詢超人的用戶名
select ui.nickname, u.username from user u join userinfo ui on u.id=ui.id where ui.nickname='超人';
3.查詢性別是男的用戶名和密碼
select u.username,u.pwd from user u join userinfo ui on u.id=ui.id where ui.gavider='男';
4.查詢是否存在 用戶名:wukong 密碼:abc 的用戶(查詢符合條件的數據條數)
select count(*) from user where username='wukong' and pwd='abc';
####一對多
--什么是一對多:有AB兩張表,A表中的一條數據對應B表中的多條數據,同時B表中的一條數據對應A表中的一條
--應用場景:用戶表和部門表,商品表和分類表
--如何創建關系:在多的一端添加外鍵指向另外一張表的主鍵
--練習:創建emp表和dept表
create table emp(id int primary key auto_increment,name varchar(15),deptno int );
create table dept(id int primary key auto_increment,name varchar(15));
insert into dept values(null ,'神仙'),(null,'妖怪');
insert into emp values(null,'豬八戒',1),(null,'白骨精',2),(null,'蜘蛛精',2);
1.查詢每個員工的姓名和對應的部門名稱
select e.name,d.name from emp e join dept d on e.deptno=d.id;
2.查詢妖怪部的員工姓名
select d.name, e.name from dept d join emp e on e.deptno=d.id where d.name='妖怪';
####多對多
--什么是多對多:有AB兩張表,A表中的一條數據對應de
--應用場景:老師表和學生表
--如何建立關系:通過第三章關系表保存兩張主表的關系
--練習:
創建老師表,學生表和關系表
create table teacher(id int primary key auto_increment,name varchar(20));
create table student(id int primary key auto_increment,name varchar(20));
create table t_s(tid int,sid int);
1.往以上表中保存蒼老師的學生小劉和小麗,傳奇老師的學生小劉,小王和小麗
insert into teacher values(null,'蒼老師');
insert into teacher values(null,'傳奇老師');
insert into student values(null,'小劉');
insert into student values(null,'小王');
insert into student values(null,'小麗');
insert into t_s value(1,1);
insert into t_s value(1,2);
insert into t_s value(2,1);
insert into t_s value(2,2);
insert into t_s value(2,3);
2.查詢每個學生姓名和對應的老師姓名
select s.*,t.name from student s join teacher t join t_s ts on s.id=ts.sid and t.id=ts.tid;
或者:select s.name,t.name from student s join t_s ts on s.id=ts.sid join teacher t on t.id=ts.tid;
3.查詢蒼老師的學生都有誰
select t.name,s.name from teacher t join t_s ts on t.id=ts.tid join student s on s.id=ts.sid where t.name='蒼老師';
4.查詢小麗的老師是誰
select s.name,t.name from student s join t_s ts on s.id=ts.sid join teacher t on t.id=ts.tid where s.name='小麗';
###自關聯
- 在當前表中添加外鍵,外鍵的值指向當前表的主鍵,這種關聯方式稱為自關聯
create table person(id int primary key auto_increment,name varchar(15),mgr int);
保存以下數據:如來->唐僧->悟空->猴崽子
insert into person values(null,'如來',null),(null,'唐僧',1),(null,'悟空',2),(null,'猴崽子',3);
1.查詢每個人的名字和和上級的名字
select p.name,m.name 上級 from person p left join person m on p.mgr=m.id;
###表設計案例:權限管理
--實現權限管理功能需要準備三張主表和兩張關系表
--創建表:
create table user(id int,name varchar(10));
create table role(id int,name varchar(10));
create table module(id int,name varchar(10));
create table u_r(uid int,rid int);
create table r_m(rid int,mid int);
--插入數據:
insert into user values(1,'劉德華'),(2,'鳳姐');
insert into role values(1,'男游客'),(2,'男會員'),(3,'女游客'),(4,'女管理員');
insert into module values(1,'男瀏覽'),(2,'男發帖'),(3,'女瀏覽'),(4,'女發帖'),(5,'女刪帖');
-保存角色和權限的關系:
insert into r_m values(1,1),(2,1),(2,2),(3,3),(4,3),(4,4),(4,5);
-保存用戶和角色的關系 劉德華男會員和女游客 鳳姐:女管理員和男游客
insert into u_r values(1,2),(1,3),(2,1),(2,4);
1.查詢每個用戶的權限有哪些
select u.name 用戶名, m.name 權限 from user u join u_r ur on u.id=ur.uid join r_m rm on ur.rid=rm.rid join module m on rm.mid=m.id;
2.查詢鳳姐的權限
select u.name 用戶名 ,m.name 權限 from user u join u_r ur on u.id=ur.uid join r_m rm on ur.rid=rm.rid join module m on rm.mid=m.id where u.name='鳳姐';
3.查詢擁有男瀏覽權限的用戶有誰
select m.name 權限,u.name 用戶名 from module m join r_m rm on m.id=rm.mid join u_r ur on rm.rid=ur.rid join user u on ur.uid=u.id where m.name='男瀏覽';
--------------------------------------------------------------------------------------------------
create table trade(tradeyid int primary key auto_increment,tradedate datetime,aomey int,directid int,way varchar(10));
create table direction(id int primary key auto_increment, relationship varchar(15),name varcahr(15),gender varchar(5));
insert into trade values(null,'2018-02-15',150,1,'微信紅包');
insert into trade values(null,'2018-01-11',120,2,'現金紅包');
insert into trade values(null,'2017-08-15',-130,3,'微信紅包');
insert into trade values(null,'2018-05-15',66,4,'支付寶紅包');
insert into trade values(null,'2018-04-15',-88,6,'現金紅包');
insert into trade values(null,'2018-01-15',99,5,'微信紅包');
insert into trade values(null,'2019-02-15',88,7,'現金紅包');
insert into trade values(null,'2018-09-15',166,11,'支付寶紅包');
insert into trade values(null,'2018-04-15',-88,8,'現金紅包');
insert into trade values(null,'2018-01-15',99,9,'微信紅包');
insert into trade values(null,'2017-02-15',88,10,'現金紅包');
insert into trade values(null,'2018-09-15',-23,12,'支付寶紅包');
insert into direction values(null,'親戚','妹妹','女');
insert into direction values(null,'同事','同事1','女');
insert into direction values(null,'朋友','朋友1','男');
insert into direction values(null,'同事','同事2','男');
insert into direction values(null,'朋友','朋友2','女');
insert into direction values(null,'親戚','哥哥','男');
insert into direction values(null,'親戚','弟弟','男');
insert into direction values(null,'朋友','朋友3','女');
insert into direction values(null,'同事','同事3','男');
insert into direction values(null,'親戚','姐姐','女');
insert into direction values(null,'朋友','朋友4','男');
insert into direction values(null,'同事','同事4','男');
insert into direction values(null,'朋友','朋友5','女');
insert into direction values(null,'親戚','表哥','男');
insert into direction values(null,'親戚','表弟','男');
insert into direction values(null,'親戚','嫂子','女');
insert into direction values(null,'同事','同事5','男');
3.統計從2018年春節(2月15日)到現在收益(收益=收入-支出) 多少紅包?
select sum(aomey) from trade where tradedate>'2018-02-15';
4.查詢從2018年(2月15日)到現在紅包大于100元的所有女性親戚的名字和對應的紅包金額
select d.name,t.aomey from trade t join direction d on t.directid=d.id where t.aomey>100 and d.relationship='親戚';
select d.name,t.aomey
from trade t join direction d
on t.directid=d.id
where time>str_to_date('2018年2月15號','%Y年%m月%d號')
and t.money not between -100
and 100 and d.gender='女'
and d.relationship='親戚';
5.查詢統計 現金 ,支付寶,微信三個平臺分別收到的紅吧總金額
select way, sum(aomey) from trade where aomey>0 group by way ;
1. 建立一個員工信息表employee,表中id(員工代碼)、sex(員工性別)、name(姓名)、departmentid(部門代碼)、
address(地址)、birthdate(生日)、postcode(郵編)、salary(薪水)、workdate(入職日期)、remark(備注信息),
其中postcode、remark 可以為空,薪水需要偉number類型,生日、入職日期為date類型,以員工代碼主鍵
create table employee(
id int primary key auto_increment,
sex char(4),
name vaechar(15),
departmentid int,
address varchar(20),
birthdate date,
postcode int null,
salary int,
workdate date,
remark text null
);
####視圖
-數據庫中包含多種對象,表和視圖都是數據庫中的對象,視圖可以理解成一張虛擬的表,視圖本質就是取代了一段sql查詢語句
-為什么使用視圖:因為有些數據的查詢需要些大量的sql查詢語句,每次書寫比較麻煩,通過使用視圖相當于把大量的sql查詢語句進行保
存,下次從視圖中查詢就不用再次書寫大量sql語句,從而提高開發效率
-視圖格式:create view 視圖名 as (子查詢);
create view v_emp_10 as (select * from emp where deptno=10);
delete from emp where sal=1300;
select * from v_emp_10;
1.創建一個沒有工資的視圖
create view v_emp_nosal as (select empno,ename,comm,mgr from emp);
2.創建視圖,視圖中顯示每個部門的工資總和,平均工資,最高工資,最低工資
create view v_emp_sum as (select sum(sal),avg(sal),max(sal),min(sal) from emp group by deptno);
-視圖的分類:
1.簡單視圖:創建視圖的時候不包含:去重,分組,函數,關聯查詢的視圖稱為簡單視圖,可以對視圖中的數據進行增刪改查
2.復雜視圖:和簡單視圖相反,只能進行查詢操作
-簡單視圖的增刪改操作 操作方式和操作table一樣
-插入數據
insert into v_emp_10 (empno,ename,deptno) values (10011,'悟空',10);
insert into v_emp_10 (empno,ename,deptno) values (10012,'八戒',20);(數據污染)
-數據污染:往視圖中插入一條在視圖中不實現但是在原表中顯示的數據,稱為數據污染
-通過with check option 關鍵字解決數據污染問題
create view v_emp_20 as (select * from emp where deptno=20) with check option;
-測試:
insert into v_emp_20 (empno,ename,deptno) values (10013,'劉備',20);//成功
insert into v_emp_20 (empno,ename,deptno) values (10014,'劉備',30);//失敗
-刪除和修改:只能操作視圖中存在的數據
-別名:如果創建視圖時使用別名 則操作視圖時只能使用別名
create view v_emp_30 as (select ename name from emp where deptno=30);
select * from v_emp_30 where ename='james';
###約束
-約束:約束是創建表時給字段添加的限制條件
####非空約束 not null
-字段值不能為null
create table t1(id int ,age int not null);
insert into t1 values(1,18);//成功
insert into t1 values(2,null)//失敗
####唯一約束 unique
-字段的值不能重復
create table t2(id int,age int unique);
insert into t2 values(1,20);//成功
insert into t2 values(2,20);//失敗
####主鍵約束
-字段的值唯一且非空
-創建表時添加主鍵約束:create table t3(id int primary key ,age int);
-創建表之后添加主鍵約束:
create table t3(id int,name varchar(10));
alter table t3 add primary key(id);
-刪除主鍵約束
alter table t3 drop primary key;
####自增
-數值只增不減
-從歷史最大值的基礎上+1
-字段值賦值為null的時候自動+1
-使用dalete 刪除全表數據 自增數值不變
-使用truncate 自增清零
####默認約束
-給字段添加默認值
create table t4(id int,age int default 10);
insert into t4 values(1,20);//默認值不生效
insert into t4 values(2,null);//默認值不生效
insert into t4 (id) values(3);//默認值生效
####檢查約束 check
-語法支持,但是沒有效果
create table t5(id int,ahe int check(age>10));
insert into t5 values (1,5);//依然成功,check沒有效果
####外鍵約束
-外鍵約束的作用:為了保證兩個表之間的關系正確建立
1.插入數據時外鍵值可以為null,可以重復,但是不能是另外一張表不存在的數據
2.被依賴的表不能被先刪除
3.被依賴的數據不能被先刪除
-如何使用外鍵:
1.創建部門表
create table dept(id int primary key auto_increment,name vaechar(10));
2.創建員工表
create table emp(id int primary key auto_increment,name varchar(10),deptid int ,constraint fk_dept foreign key(deptid) references dept(id));
-介紹:
constraint 約束名稱 foreign key(外鍵字段名) references 表名(字段名)
-測試:
insert into dept values(null,'神仙'),(null,'妖怪');
insert into dept values(null,'八戒',1);//成功
insert into dept values(null,'悟空',1);//成功
insert into dept values(null,'超人',3);//失敗,沒有3
drop table dept;//失敗
delete from dept where id=2;//成功
delete from dept where id=1;//失敗
###索引
-什么是索引:索引是數據庫中提高查詢效率的技術,類似于字典的目錄
-為什么使用索引:如果不使用索引數據會零散的保存在每一個磁盤塊當中,查詢數據時需要挨個的遍歷每一個磁盤塊查找數據,如果數據量超級大,遍
歷每一個磁盤塊是件非常耗時的事件,添加索引后,會將磁盤塊以樹狀結構進行保存,查詢數據時會會有目的性的訪問部分磁盤塊,因為訪問的磁盤塊
數量降低所以能起到提高查詢效率的作用
-索引是越多越好么?
不是,因為索引會占磁盤空間,通過某個字段創建的索引可能永遠用不上,則這個索引完全沒有存在的意義,只需要對查詢時頻繁使用的字段創建索引
-有索引就一定好嗎?
不一定,如果數據量小使用索引反而會降低查詢效率.
-索引的分類(了解)
1.聚集索引(聚簇索引):通過主鍵創建的索引為聚集索引,添加了主鍵約束的表會自動添加聚集索引,聚集索引的樹樁結構中保存了數據
2.非聚集索引:通過非主鍵字段創建的索引叫作非聚集索引,樹樁結構中只保存了數據所在磁盤塊的地址并沒有數據
-創建索引的格式:
create index 索引名 on 表名(字段名[(字符長度)]);
create index i_item_title on item2(title);
-創建完后繼續執行
select * from item2 where title='100'; //看一下耗時 0.02秒
-查看索引:
show index from item2;
-刪除索引
drop index 索引名 on 表名;
drop index i_item_title on item2;
-復合索引
通過多個字段創建的索引稱為復合索引
-格式:create index 索引名 on 表名(字段1,字段2);
頻繁使用多個字段進行數據查詢時為了提高查詢效率可以創建復合索引
select * from item2 where title='100' and price<100;
create index i_item_title_price on item(title,price);
-總結:
1.索引是用于提高查詢效率的技術,類似目錄
2.索引會占用磁盤空間不是越多越好
3.如果數據量小的話,添加索引會降低查詢效率
4.盡量不要在頻繁改動的表上添加索引
###事務
-數據庫中執行sql語句的最小工作單元,保證事務中的多條sql全部成功或全部失敗
-事務的ACID特性:
1.Atomicity:原子性, 最小不可拆分 保證全部成功或全部失敗
2.Consistency:一致性, 從一個一致狀態到另外一個一致狀態
3.Isolation:隔離性, 多個事務之間互相隔離互不影響
4.Durability:持久性, 事務提交后數據持久保存到數據庫文件中
-事務相關指令:
-查看自動提交狀態:show variables like '%autocommit%'
-修改自動提交:set autocommit=0/1;
-提交:commit;
-回滾:rollback;
-保存回滾點:savepoint s1;
-回滾到指定回滾點:rollback to s1;
###group-concat() 分組連接函數
1.查詢員工表中 每個部門的所有員工工資
select deptno,group_concat(sal) from emp group by deptno;
2.查詢員工表中,每個部門的員工姓名和對應的工資,要求顯示到一條數據中
select deptno,group-concat(ename,sal) from emp group by deptno;
###面試題:
有個學生表student (id,name,subject,score)
保存以下數據:
張三 語文 66 , 張三 數學 77 , 張三 英語 55 , 張三 體育 77
李四 語文 59 , 李四 數學 88 , 李四 英語 78 , 李四 體育 95
王五 語文 75 , 王五 數學 54 , 王五 英語 98 , 王五 體育 88
create table student(id int primary key auto_increment,name varchar(15),subject varchar(5),score int not null);
insert into student values(null,'張三','語文',66);
insert into student values(null,'張三','數學',77);
insert into student values(null,'張三','英語',55);
insert into student values(null,'張三','體育',77);
insert into student values(null,'李四','語文',59);
insert into student values(null,'李四','數學',88);
insert into student values(null,'李四','英語',78);
insert into student values(null,'李四','體育',95);
insert into student values(null,'王五','語文',75);
insert into student values(null,'王五','數學',54);
insert into student values(null,'王五','英語',98);
insert into student values(null,'王五','體育',88);
1.查詢每個人的平均分 從大到小排序
select name, avg(score) 平均分 from student group by name order by 平均分 desc;
2.每個人的姓名 科目 成績 一行顯示出來
select name,group_concat(subject,score) from student group by name;
3.查詢每個人的最高和最低分
select name,max(score) 最高分,min(score) 最低分 from student group by name;
4.查詢每個人不及格的科目以及分數和及格的科目數量
select name,group_concat(subject,':',score+'') , count(*) from student where score<60 group by name;
####JDBC
- JDBC:Java DataBase Connectivity.java數據庫連接,實際上jdbc是java中的一套和數據庫進行交互的api(application program interface 應用程序編程接口)
- 為什么使用JDBC:因為Java程序員需要連接多種數據庫,為了避免每一種數據庫都學習一套新的api,Sun公司提出了一個JDBC的接口,各個數據庫的廠商根據此
接口寫實現類(驅動),這樣java程序員只需要掌握JDBC接口的調用,即可訪問任何數據庫。
###如何使用JDBC連接MySQL數據庫
1. 創建Maven工程
2. 登錄maven私服的網站 maven.tedu.cn 外網 倉庫服務
首頁搜索MySQL 找到 5.1.6版本 把坐標復制到pom.xml中
3. 創建Demo01.java類 添加main方法
-通過以下代碼連接數據庫并執行sql語句
//1.注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2.獲取鏈接對象
Connection conn=DriverManager.getConnection
("jdbc:mysql://localhost:3306/db1",
"root","root");
//3.創建SQL執行對象
Statement stat=conn.createStatement();
//4.執行SQL
String sql="create table jdbc(id int,name varchar(10))";
stat.execute(sql);
System.out.println("創建完成!");
//5.關閉資源
stat.close();
conn.close();
###JUnit Test單元測試
-在無參無返回值的方法上面添加@Test注解,通過右鍵 run as 執行 綠色代表執行成功,紅色執行失敗
###執行SQL的方法
-execute();此方法可以執行任意的SQl 但是推薦執行DDL (數據定義語言 create,drop,alter,truncate) 返回值為boolean值 返回值代表的是是否有結果集(只有查詢語句有結果集)
-executeUpdate(); 增刪改操作全部使用此方法 返回值為int 表示生效的行數
-executeQuery(); 此方法執行查詢操作 返回ResultSet 通過while循環遍歷
代碼如下:
//執行查詢 得到的結果封裝在了resultset中
ResultSet rs=stat.executeQuery(sql);
//遍歷結果集
while(rs.next()){
int empno=rs.getInt("empno");
String name=rs.getString("ename");
double sal=rs.getDouble("sal");
System.out.println(empno+","+name+","+sal);
}
-從ResultSet中獲取數據的兩種方式:
1. 通過表字段的名稱獲取
2. 通過結果中字段的位置獲取 (以本次查詢的字段順序為準,并非表字段的順序)
####自定義模板代碼
window->preferense->java->editor->templates->new
###數據庫連接池 DBCP
- 為什么用連接池:如果沒有連接池一萬次請求會對應一萬次和數據庫服務器的連接和斷開連接操作,使用連接池之后可以將連接池中的連接復用,從而提高執行效率
- 使用方式:
//創建數據源對象
BasicDataSource dataSource =
new BasicDataSource();
//設置數據庫連接信息
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db1");
dataSource.setUsername("root");
dataSource.setPassword("root");
//設置初始連接數量
dataSource.setInitialSize(3);
//設置最大連接數量
dataSource.setMaxActive(5);
//從連接池中獲取連接
Connection conn =
dataSource.getConnection();
System.out.println(conn);
###PreparedStatement預加載的SQL執行對象
- 好處:
1. 代碼更直觀,簡潔
2. 可以避免SQL注入,因為在預編譯時已經把sql邏輯固定鎖死,不會被之后替換進去的值改變原有邏輯
###批量操作batch
因為每次sql的執行都需要和數據庫服務器進行數據傳輸,如果執行的sql太多每次和數據庫進行交互浪費資源執行效率低,使用批量操作可以把多條SQL語句合并到一次交互中,這樣可以提高執行效率
- Statement
//添加到批量操作
stat.addBatch(sql1);
stat.addBatch(sql2);
stat.addBatch(sql3);
//執行批量操作
stat.executeBatch();
- PreparedStatement
stat = conn.prepareStatement(sql);
stat.setString(1, "劉備");
stat.setString(2, "aaa");
//添加到批量處理
stat.addBatch();
stat.setString(1, "關羽");
stat.setString(2, "bbb");
//添加到批量處理
stat.addBatch();
stat.setString(1, "張飛");
stat.setString(2, "ccc");
//添加到批量處理
stat.addBatch();
//執行
stat.executeBatch();
###事務
1. 關閉自動提交
conn.setAutoCommit(false/true);
2. 提交
conn.commit();
3. 回滾
conn.rollback();
- 案例 參見代碼:Demo11.java
###獲取自增主鍵的值
rs=stat.getGeneratedKeys();
create table team(id int primary key auto_increment,name varchar(10));
create table player(id int primary key auto_increment,name varchar(10),teamid int);
- 球隊和球員案例代碼參見: Demo11.java
####數據庫的元數據和表的元數據 代碼參見:Demo12.java
create table city(id int primary key auto_increment,cityname varchar(10),Pid int);
create table provice(id int primary key auto_increment,provicename varchar(20),Iid int);
create table user(id int primary key auto_increment,email varchar(32),pwd varchar(16),Pid int,Iid int);
create table information(id int primary key auto_increment,nickname varcahr(12),forumnickname varchar(12),gender varchar(2),birthday date,Pid int,Cid int);
select say 單價,num 庫存,say*num 總金額 from t_item;
html中的高度坍塌;
總結
以上是生活随笔為你收集整理的mysql 表字段信息从一张表迁移到另一张表_MySQL(数据库)笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奥比岛电脑版下载(奥比岛电脑版下载安装)
- 下一篇: 电脑cpu-z在哪下载(CPU-Z中文版