MySQL笔记_MySQL的再探

MySQL笔记_MySQL的再探

呈: MySQL笔记_MySQL的小试

连接查询

  • 多张表联合查询,连接方式: 1. 内连接:等值连接、非等值连接、自连接。2. 外连接:左(外)连接、右(外)连接、全连接。

  • 笛卡尔积:若两张表进行连接查询 无过滤条件 则 条数 为 两表条数乘积

  • 找出 员工的部门名称

  mysql> select e.ename,d.dname from emp e ,dept d;
  -- 上条 更好 且 需要起 别名 易于 分别 且效率更高 可读性好
  mysql> select ename,dname from emp,dept;
  +--------+------------+
  | ename  | dname      |
  +--------+------------+
  | SMITH  | ACCOUNTING |
  | SMITH  | RESEARCH   |
  | SMITH  | SALES      |
  | SMITH  | OPERATIONS |
  | TURNER | SALES      |
  | TURNER | OPERATIONS |
  | ADAMS  | ACCOUNTING |
  | ADAMS  | RESEARCH   |
  | ADAMS  | SALES      |
  | ADAMS  | OPERATIONS |
  ...
  | MILLER | SALES      |
  | MILLER | OPERATIONS |
  +--------+------------+
  56 rows in set (0.01 sec) -- 56 = 14 * 4

 

ps:避免 笛卡尔积现象,同时不会减少记录的匹配次数,因而可以用来where,having加条件。

 mysql> select e.ename,d.dname
     -> from emp e , dept d
     -> where  
     -> e.deptno = d.deptno;//92语法 不用
 +--------+------------+
 | ename  | dname      |
 +--------+------------+
 | CLARK  | ACCOUNTING |
 | KING   | ACCOUNTING |
 | MILLER | ACCOUNTING |
 | SMITH  | RESEARCH   |
 | JONES  | RESEARCH   |
 | SCOTT  | RESEARCH   |
 | ADAMS  | RESEARCH   |
 | FORD   | RESEARCH   |
 | ALLEN  | SALES      |
 | WARD   | SALES      |
 | MARTIN | SALES      |
 | BLAKE  | SALES      |
 | TURNER | SALES      |
 | JAMES  | SALES      |
 +--------+------------+
 14 rows in set (0.01 sec)

内连接

  1. 内连接 --> 等值连接

    条件是 等量关系 则可以分离条件

select e.ename, d.dname 
from emp e
(inner)join dept d 		--inner 可以省略 带上更清晰 
on e.deptno = d.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
+--------+------------+
14 rows in set (0.00 sec)
语法
select 
	e.ename,d.dname
from 
	emp e 
join
	dept d
on 
	连接条件
where 
	过滤条件
  1. 内连接 --> 非等值 连接
select e.ename,e.sal,s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
  1. 内连接–>自连接

eg. 找到每个员工 的上级领导(13条记录 忽略NULL)

select a.ename,b.ename
from emp a
join emp b
on a.mgr = b.empno;
+--------+-------+
| ename  | ename |
+--------+-------+
| SMITH  | FORD  |
| ALLEN  | BLAKE |
| WARD   | BLAKE |
| JONES  | KING  |
| MARTIN | BLAKE |
| BLAKE  | KING  |
| CLARK  | KING  |
| SCOTT  | JONES |
| TURNER | BLAKE |
| ADAMS  | SCOTT |
| JAMES  | BLAKE |
| FORD   | JONES |
| MILLER | CLARK |
+--------+-------+
13 rows in set (0.00 sec)
-- 将两张表看作一张表进行自连接 关键要找到合适的关系
-- 上表King无 上级

外连接

区别:与内链接 -能够匹配记录可以查询出来 就是内链接 且 无主辅之分

外连接:分主次 若副表 无主表数据 模拟NULL与之匹配

左连接 右连接 指的是主表的位置 可以相互替换 不忽略匹配不上的情况。

mysql> select a.ename,b.ename
    -> from emp a
    -> left(outer) join emp b
    -> on a.mgr = b.empno;    
-- or
mysql> select a.ename,b.ename
    -> from emp b
    -> right(outer) join emp a
    -> on a.mgr = b.empno;   
+--------+-------+
| ename  | ename |
+--------+-------+
| SMITH  | FORD  |
| ALLEN  | BLAKE |
| WARD   | BLAKE |
| JONES  | KING  |
| MARTIN | BLAKE |
| BLAKE  | KING  |
| CLARK  | KING  |
| SCOTT  | JONES |
| KING   | NULL  |
| TURNER | BLAKE |
| ADAMS  | SCOTT |
| JAMES  | BLAKE |
| FORD   | JONES |
| MILLER | CLARK |
+--------+-------+
14 rows in set (0.00 sec)
-- 主表数据 无条件 全部查询出来

左右连接

eg: 找出哪个部门没有员工

mysql> select e.*[可以省略],d.*        
    -> from emp e
    -> right join dept d 
    -> on e.deptno = d.deptno 
    -> where  e.empno is NULL;
+-------+-------+------+------+----------+------+------+--
|EMPNO|ENAME|JOB|MGR| HIREDATE|SAL|COMM|DEPTNO|DEPTNO|
+-------+-------+------+------+----------+------+------+--
|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|40|OPERATIONS|  
+-------+-------+------+------+----------+------+------+--
1 row in set (0.00 sec)
mysql> select d.*              
    -> from emp e              
    -> right join dept d 
    -> on e.deptno = d.deptno  
    -> where  e.empno is NULL;
+--------+------------+--------+
| DEPTNO | DNAME      | LOC    |
+--------+------------+--------+
|     40 | OPERATIONS | BOSTON |
+--------+------------+--------+
1 row in set (0.00 sec)
  • 三张表 的 连接

    eg:找出 每一个员工的 部门名称 和 薪资等级

    -- 找出 每一个员工的 部门名称  和 薪资等级
    ...
    -- A
    -- join B
    -- join C
    -- A 先 和B连接 结果在和 C连接
    select e.ename,d.dname,s.grade,e1.ename as authorname
    from emp e
    join dept d
    on e.deptno = d.deptno
    join salgrade s
    on e.sal between s.losal and s.hisal
    left join emp e1
    on e.mgr = e1.empno;
    +--------+------------+-------+
    | ename  | dname      | grade |
    +--------+------------+-------+
    | SMITH  | RESEARCH   |     1 |
    | ALLEN  | SALES      |     3 |
    | WARD   | SALES      |     2 |
    | JONES  | RESEARCH   |     4 |
    | MARTIN | SALES      |     2 |
    | BLAKE  | SALES      |     4 |
    | CLARK  | ACCOUNTING |     4 |
    | SCOTT  | RESEARCH   |     4 |
    | KING   | ACCOUNTING |     5 |
    | TURNER | SALES      |     3 |
    | ADAMS  | RESEARCH   |     1 |
    | JAMES  | SALES      |     1 |
    | FORD   | RESEARCH   |     4 |
    | MILLER | ACCOUNTING |     2 |
    +--------+------------+-------+
    -- ----------------------------------------加领导名
    +--------+------------+-------+------------+
    | ename  | dname      | grade | authorname |
    +--------+------------+-------+------------+
    | SMITH  | RESEARCH   |     1 | FORD       |
    | ALLEN  | SALES      |     3 | BLAKE      |
    | WARD   | SALES      |     2 | BLAKE      |
    | JONES  | RESEARCH   |     4 | KING       |
    | MARTIN | SALES      |     2 | BLAKE      |
    | BLAKE  | SALES      |     4 | KING       |
    | CLARK  | ACCOUNTING |     4 | KING       |
    | SCOTT  | RESEARCH   |     4 | JONES      |
    | KING   | ACCOUNTING |     5 | NULL       |
    | TURNER | SALES      |     3 | BLAKE      |
    | ADAMS  | RESEARCH   |     1 | SCOTT      |
    | JAMES  | SALES      |     1 | BLAKE      |
    | FORD   | RESEARCH   |     4 | JONES      |
    | MILLER | ACCOUNTING |     2 | CLARK      |
    +--------+------------+-------+------------+
    14 rows in set (0.00 sec)
    
    • from 后 嵌套子查询

      eg:找出每个部门 的 平均薪水的 薪资等级

      1. 找出每个部门的 平均薪水 (按照部门标号 分组 求 平均薪资)
      select deptno,avg(sal) from emp group by deptno;
      +--------+-------------+
      | deptno | avg(sal)    |
      +--------+-------------+
      |     10 | 2916.666667 |
      |     20 | 2175.000000 |
      |     30 | 1566.666667 |
      +--------+-------------+
      mysql> select t.*,s.grade                                        
          -> from (select deptno,avg(sal) as avgsal from emp group by deptno) t
          -> join salgrade s
          -> on t.avgsal between s.losal and hisal;
      +--------+-------------+-------+
      | deptno | avgsal      | grade |
      +--------+-------------+-------+
      |     30 | 1566.666667 |     3 |
      |     10 | 2916.666667 |     4 |
      |     20 | 2175.000000 |     4 |
      +--------+-------------+-------+
      
      
      
    • 找出每个部门 平均的薪水等级

      mysql> select e.deptno,avg(s.grade) 
      > from emp e 
      > join salgrade s 
      > on e.sal between s.losal and s.hisal
      > group by e.deptno;
      
    • 在 select 后 嵌套 子查询

      select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname
      from emp e;
      +--------+------------+
      | ename  | dname      |
      +--------+------------+
      | SMITH  | RESEARCH   |
      | ALLEN  | SALES      |
      | WARD   | SALES      |
      | JONES  | RESEARCH   |
      | MARTIN | SALES      |
      | BLAKE  | SALES      |
      | CLARK  | ACCOUNTING |
      | SCOTT  | RESEARCH   |
      | KING   | ACCOUNTING |
      | TURNER | SALES      |
      | ADAMS  | RESEARCH   |
      | JAMES  | SALES      |
      | FORD   | RESEARCH   |
      | MILLER | ACCOUNTING |
      +--------+------------+
      14 rows in set (0.00 sec)
      

    union 联合查询

    • union 可以将 查询结果集 相加

      -- 找出 工作岗位是 salesman 和 manager 的员工
      -- 第一种 or
      mysql> select ename,job 
          -> from emp 
          -> where job = 'MANAGER' or job = 'SALESMAN';  
      -- 第二种 in
      mysql> select ename,job 
          -> from emp
          -> where job in('MANAGER','SALESMAN');
      -- 第三种 union
      mysql> select ename,job from emp where job = 'MANAGER'  
          -> union
          -> select ename,job from emp where job = 'SALESMAN';
      +--------+----------+
      | ename  | job      |
      +--------+----------+
      | JONES  | MANAGER  |
      | BLAKE  | MANAGER  |
      | CLARK  | MANAGER  |
      | ALLEN  | SALESMAN |
      | WARD   | SALESMAN |
      | MARTIN | SALESMAN |
      | TURNER | SALESMAN |
      +--------+----------+
      7 rows in set (0.00 sec)
      

limit 限制查询

往往用于分页或排序查询来限制结果的显示方式

其中:

  1. MySQL特有limit 查询 ,Oracle 有类似机制 rownum

  2. limit 只取结果集中的 部分数据

  3. limit 命令格式 :limit startIndex,length

ps:起始值 startIndex(从零开始,可以不写) 长度length

  1. limit 最后执行
  • 找出收入倒序排列的前5位
 mysql> select ename,sal from emp order by sal desc limit 0,5; 

 +-------+---------+

 | ename | sal   |

  +-------+---------+

  | KING | 5000.00 |

  | SCOTT | 3000.00 |

  | FORD | 3000.00 |

  | JONES | 2975.00 |

  | BLAKE | 2850.00 |

  +-------+---------+
  5 rows in set (0.01 sec)

eg:找出4-9名工资排名

mysql> select ename,sal   

-> from emp 

-> order by sal desc

-> limit 3,6;

  +--------+---------+  

  | ename | sal   |  

  +--------+---------+  

  | JONES | 2975.00 |  

  | BLAKE | 2850.00 |  

  | CLARK | 2450.00 |  

  | ALLEN | 1600.00 |  

  | TURNER | 1500.00 |  

  | MILLER | 1300.00 |  

  +--------+---------+  

  6 rows in set (0.00 sec)
  -- 通用 翻页 每页显示 pageSize条记录

  -- 第 pageNo 页 (PageNo - 1) *pageNo = pageSize

MySQL 常见 数据类型

与 Java 数据类型 对应理解记忆, 分别有 int、 bigint 、long;float 、double; char、varchar(类似Java StringBuilder构造的字符串 )、date(from java.sql.Date); BLOB二进制大对象(存储图片、视频 等流媒体信息) Binary Large Object;CLOB字符大对象 存储较大文本 可以存储 4G 字符串 Character Large Object。

eg. id(int) name(varchar) playtime(date/char) seal(BLOB) - IO流 history(CLOB)

char 与 varchar 的区别

char 效率高 不用判断 长度, char(6) 少补 多错 varchar(6) 智能分配
char 字段数据长度 是定长的 eg. 性别、生日
varchar eg.简介 姓名

DQL 语句

  1. 建表语句
-- 语法 
> create table 表名(

 字段名:数据类型,

 字段名:数据类型,

 字段名:数据类型,

 字段名:数据类型,

  ...

);
--   一般 数据库 创建表格时 建议 以 t_/tbl_ 
-- t_movie 命名
  • eg.建立一个 拥有 “学号 姓名 性别 班级编号 生日” 的学生表格
 -- 学号 姓名 性别 班级编号 生日
 create table t_stu(

   no bigint,

   name varchar(255),

   sex char(1),

   classno varchar(255),

   birth char(10)

 );
  Query OK, 0 rows affected (0.01 sec)
  mysql> desc t_stu;
	  
+---------+--------------+------+-----+-------+
| Field  | Type| NULL | Key | Default | Extra |
+---------+--------------+------+-----+-------+
| no   | bigint(20)  | YES |   | NULL  |      |
| name  | varchar(255) | YES |   | NULL|      |
| sex   | char(1)   | YES |   | NULL  |    	  |
| classno | varchar(255) | YES |   | NULL|    |
| birth  | char(10)   | YES |   | NULL  |     |
+---------+--------------+------+-----+-------+
5 rows in set (0.00 sec)
  1. 插入数据 insert
    -- 语法:
    insert into 表名(
      字段名,
      字段名,
      字段名,
      )
   values
   (
      val1,
      val2,
      val3,
   ) ;
   -- ps :值和字段的数量要相同 且 数据类型要对应
  • 插入方式,所有字段都赋值,或只给单个字段赋值。

    insert into t_stu(
         no,name,sex,classno,birth
    
     )values(
    
         1,'Zhangsan','f','gaosan1ban','1980-10-23'
    
     );
     -- 插入 一个字段 其他值 自动 赋值NULL 且 顺序可变
     
    insert into t_student(name)values('Zhangsan');    
    
        Query OK, 1 row affected (0.01 sec)
    	
    
  1. 删表
drop table if exists t_stu;

   create table t_student(

     no bigint,

     name varchar(255),

     sex char(1) default 1,//指定默认值

     classno varchar(255),

     birth char(10)

   )
  1. 更新表

当 insert 执行 一次 表中新产生一行 忽略NULL 且 不能再用insert 插入 只能用 update 更新
若按顺序 插入 前方 字段 默认 按 插入 顺序 和 数量 执行

ps.如果没有条件 则 全表更新

-- 语法格式: 

  update 表名 set 
   
  字段1=值1,
   
  字段2=值2,
   
  where conditon ;
	  -- 更新示例
	  -- 插入单行数据
	    insert into t_student values(
	      10,
	      'Zhangsan',
	      'gaoshan',
	      );  
	   -- 插入多行数据
	     insert into t_student values(
	     20,
	     'Lisi',
	       'gaoshan',
	 ),(
	30,
	'Wangwu',
	'gaoshan',
	   ); 
	       
	 		update dept1 set loc = 'SHANGHAI',dname = 'RENSHIBU' where deptno = 10; 
	    
	        mysql> update dept1 set loc = 'x',dname = 'y';
	    
	        Query OK, 3 rows affected (0.00 sec)
	    
	        Rows matched: 3 Changed: 3 Warnings: 0
	        mysql> select * from dept1;
	    
	         +--------+-------+------+
	    
	         | DEPTNO | DNAME | LOC |
	    
	         +--------+-------+------+
	    
	         |   10 | y   | x  |
	    
	         |   20 | y   | x  |
	    
	         |   30 | y   | x  |
	    
	         +--------+-------+------+
	    
	         4 rows in set (0.00 sec)

  1. 表的复制

    create table 表名 as dql 语句;

    create table emp1 as select ename,sal from emp;
  --  将 查询结果 赋作 新表

    create table emp1 as select* from emp;
  --  将 查询结果 插入 一张表	
  1. 删除数据 不删除表格
  • 语法格式
  -- 删除 可以 回滚 rollback
  mysql>delete from table0 where conditions 
  /*if no condition delete all data*/
  -- 截断 不可回滚 
  mysql> truncate table emp1;
  Query OK, 0 rows affected (0.01 sec)
  1. DDL 对表结构 修改 可以借助工具 且 很少发生
CRUD ---> R --> create retrieve update delete

约束(Constraint)

非空约束(not NULL) 确保数据 合法、有效、完整性

唯一性约束(unique) 用户名 方便管理 不能重复

主键约束(primary key) : 不能为NULL 且不能 重复(PK)

外键约束(foriegn key)(FK)

检查约束(check) : Oracle 支持 check 约束 mysql 不支持该约束

  1. 非空约束 not NULL
drop table if exists t_user;
create table t_user(
id int,
username varchar(255) not NULL,
password varchar(255) not NULL,
);
insert into t_user(id,password) values(1,'123');
1364 ---> 缺 默认值
  1. 唯一性约束 unique

唯一 约 束 修饰 的 字段具有唯一性 不能重复 但 可以为NULL

drop table if exists t_user;
create table t_user(
id int,
username varchar(255) unique -- 列级约束
);
insert into t_user values(1,'Zhangsan');
insert into t_user values(2,'Zhangsan');

同时加 unique


drop table if exists t_user; 
create table t_user(
	id int,
usercode varchar(255),
username varchar(255),
unique(usercode,username) -- 加一个约束 表级约束
);
insert into t_user values(1,'111','Zhangsan');
insert into t_user values(2,'111','Lisi');
insert into t_user values(3,'222','Zhangsan');
select * from t_user;
mysql> select * from t_user; 
+------+----------+----------+
| id   | usercode | username |
+------+----------+----------+
|    1 | 111      | Zhangsan |
|    2 | 111      | Lisi     |
|    3 | 222      | Zhangsan |
+------+----------+----------+
3 rows in set (0.00 sec)
------------------分别加约束----------------------
drop table if exists t_user;
create table t_user(
	id int,
usercode varchar(255) unique,
username varchar(255) unique
);
insert into t_user values(1,'111','Zhangsan');
insert into t_user values(2,'111','Lisi');
  1. 主键约束
drop table if exists t_user;
   create table t_user(
   id int primary key,
   username varchar(255)
   -- primary key(id)
   );

写在最后

MySQL的探索还在路上,加油!!

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值