2019-03-24 SQL常用语句(二)

1.数据完整性

在查询的时候可以没有外键约束,就算没有外键约束也可以进行查询,但是在添加,更新的时候必须要有。

保证用户输入的数据保存到数据库当中是正确的(保存到数据库当中的数据是正确的)。具体做法是在建表的时候给约束,完整性可以分为一下三类

实体完整性
域完整性
引用完整性

(一)实体完整性

表当中的一行就代表一个实体,实体完整性的作用是约束每一行的数据不能重复,完整性约束主要可以分为一下三类

主键约束(primary key)
唯一约束(unique)
自动增长列(auto_increment)
1.主键约束

特点:每个表当中要有一个主键,并且数据唯一,不能为null
添加方式:

**********************建表的同时创建主键*****************
create table 表名(字段1 数据类型  primary key,字段2 数据类型.....字段n 数据类型);
create table 表名(字段1 数据类型,字段2 数据类型....primary key(要设置主键的字段));
create table 表名(字段1 数据类型,字段2 数据类型....primary key(主键1,主键2...));
*********************先建表,在创建主键******************************** 
1.建表
2.修改表,添加主键
alter table 表名 add constraint primary key (id);
image.png
create table person(
    id bigint primary key,
    name varchar(10)
);
**********************************************
create table person(
    id bigint,
    name varchar(10),
    age int,
    primary key (id)
);
******************************************************
-- 联合主键,两个主键合起来作为一个联合主键,
-- 两个主键都不能为null,不能有2个重复,可以有1个重复
create table student(
    id bigint,
    snum bigint,
    sname varchar(10),
    primary key(id,snum)
);

*********************************************
alter table students add constraint primary key(id);
2.唯一性约束
image.png

特点:指定列的数据不能重复,可以为null(可以有多个)
格式:

create table 表名(字段1 数据类型 unique,字段二 数据类型......);

注意主键约束可以有多个null

create table student(
    id bigint primary key,
    name varchar(50) unique,
    age int
); 
3.字段增长列
image.png

特点:指定列的数据自动增长,即使数据删除了,还是村删除的序号往下继续增长。
格式:

create table 表名(字段1 数据类型 primary key auto_increment,字段2 数据类型....);
create table student(
    id bigint primary key auto_increment,
    name varchar(20) unique,
    age int
);

(二)域完整性

使用:限制此单元格的数据正确,不与此列的其他单元格进行比较,域代表当前当单元格。
域完整性约束主要分为一下三个方面:

数据类型:数值类型,日期类型,字符串类型
非空约束(not null)
默认值约束(default)
1.非空约束,默认值约束
create table 表名(字段1 数据类型 not null,字段2 数据类型....);
create table 表名(字段1 数据类型 default '男',字段2 数据类型....);
create table student(
    id bigint primary key auto_increment,
    name varchar(50) unique not null,
    gender char(2) default '男'
);

(三)参照完整性

什么是参照完整性:是指表于表之间的一种对应关系,通常情况下可以通过设置2张表之间的主键,外键关系,或者编写2张表的触发器来实现,有对应参照完整性的2张表,对他们的数据进行插入删除更新操作的时候,系统都会将被修改表格与另一张对应的表格进行对照,从而阻止一些不正确的数据的操作。

数据库的主键和外键类型必须要一致
2个表必须要是Innodb类型
设置参照完整性后,外键当中的内值,必须是主键当中的内容
一个表设置当中的字段为主键,设置主键的为主表
创建表时,设置外键,设置外键的为子表
create table  stu(
    id int primary key,
    name varchar(50),
    age int
);
-- 设置score当中的sid为外键,和stu当中的主键id关联
create table score(
    sid int,
    score  int,
    constraint sc_st_fk foreign key (sid) references stu(id)
);
***************如果表以及建好了,可以使用SQL语句添加外键***********
alter table score add constraint foreign key (sid) references stu(id);

2.多表关系的创建

创建多对多关系的方法:创建一个中间关系表来实现

image.png

-- 多对多,要创建中间表
create table teacher(
    tid int primary key ,
    name varchar(50)
);
create table student(
    sid int primary key,
    name varchar(50)
);
-- 注意此处的字段名不能乱写,必须要是前两个表的主键,不然是无用的
create table tea_stu_rel(
    tid int,
    sid int
);
-- 添加中间表与其他表的联系(设置外键),中间表当中的字段都要设置外键.
alter table tea_stu_rel add constraint foreign key (tid) references teacher(tid);
alter table tea_stu_rel add constraint foreign key (sid) references student(sid);
总结:中间表约束创建完成之后,添加到中间表当中的数据全部是表一表二当中的数据,加入其他的数据会报错。

3.外什么要拆分表?

为了避免大量冗余数据的出现

image.png

4.多表查询

多表查询大致分为以下四个方面:

合并结果集
连接查询
子查询
自连接

(一)合并结果集

image.png
-- 合并结果集
create table A(
    name varchar(50),
    score int
);
create table B(
    name varchar(20),
    score int
);
insert into A values('a',80),('b',90);
insert into B values('a',80),('c',90),('b',100),('d',120)
select * from A union select * from B;
select * from A union all select * from B;
******************************************************
注意:在合并结果集的时候,要求2张表的列和列数据类型一致,不然不能合并

(二)连接查询

image.png
*********************多表查询会出现笛卡尔积结果集***********************
select * from student,teacher
笛卡尔积的记录书:A记录数*B记录数
1.如何保证数据的正确性,避免笛卡尔积结果集?
image.png
select * from stu,score where stu.id=score.sid;
***************************************************
在查询时保持主键和外键的一致性
主表当中的数据参照子表当中的数据
原理:逐行判断,相等的留下,不相等的全部要。
2.连接查询分类
注意查询的时候可以没有主外键约束

连接查询主要可以分为以下三类:

内连接
外连接
自然连接
(一)内连接

内连接可以分为如下的三种:

等值连接
多表连接
非等值连接
1.等值连接
**********************内连接*********************************
-- 注意查询的时候虽然没有主外键约束,但是我们在心里面应该明白有主外键约束
-- 99写法
select * from stu st,score sc where st.id=sc.id;
select * from stu st inner join score sc on st.id=sc.id;
select * from  stu st join score sc on st.id=sc.id;
*******************************************************
select * from stu st join score sc on st.id=sc.id where score>80;
2.多表连接

image.png

表如下:


image.png
-- 查询处学生的姓名,分数,科目,在此处是三表查询
select st.name,sc.score ,cs.name from stu st,score sc ,course cs
where st.id=sc.id and sc.sid=cs.cid;
*******************************************************************
select st.name,cs.name,sc.score from stu st 
    inner join score sc on st.id=sc.id
    inner join course cs on sc.sid=cs.cid;
查询结果
总结:在进行多表查询的时候,具体的做法是一步一步,两表进行查询。
3.非等值连接

非等值查询:即查询后面的条件不是等值的

image.png

-- 查询所有员工的姓名,工资,所在部门名称以及该工资的等级
select emp.ename,emp.salary ,dept.dname ,salgrade.grade from 
    emp,dept ,salgrade
    where emp.deptno=dept.deptno
    and emp.salary>=salgrade.lowSalary 
    and emp.salary<=salgrade.higghSalary;
***************************************************
select e.ename,e.salary,d.dname,s.grade from emp e 
    inner join dept d on e.deptno=d.deptno
    inner join salgrade s on  e.salary between s.lowSalary and s.higghsalary;
(二)外连接

外连接可以分为:

左外连接(左连接)
右外连接(右连接)
1.左连接

将2表满足条件的数据查询出来,如果左边表右不同的数据,被左边表当中的数据查询出来

select * from stu st left  outer join score sc on st.id=sc.id;
2.右链接
image.png
select * from stu st right  outer join score sc on st.id=sc.id;
(三)自然连接
image.png
-- 不加where条件的时候,求出的结果是笛卡尔积的结果
select * from stu,score;
select * from stu ,score where stu.id=score.id;
select * from stu inner join score on stu.id=score.id;

-- 自然连接,当有相同列名及数据类型的时候,会按照主外键查
-- 如果没有对应的,会进行笛卡尔积查询
select * from stu natural join score;

总结:


表之间连接关系

4.子查询

什么是子查询:一个select语句当中包含另一个select语句,或者多个select语句。
子查询出现的位置:

where后:把select查询出来的结果当成另一个select的条件值。
from后:把查询出来的结果当成一个新表。

(一)where后

查询出和项羽同部门的员工名称

-- 查询与项羽同一部门的员工
-- 先查询项羽所在的部门,再查询同部门人员
select emp.deptno from emp where emp.ename='项羽' ;
select ename ,empno from emp 
    where deptno=(select emp.deptno from emp where emp.ename='项羽');

(二)from后

查询30号部门里面所有员工的薪资

-- 查询30号部门所有薪资大于2000的员工
-- 先查询30号部门的员工的工资,再查询大于2000的
select ename,salary from emp where deptno=30;
select es.ename ,es.salary from (select ename,salary from emp where deptno=30) es
where es.salary>2000;

(三)练习

-- 查询薪资高于程咬金的员工
第一步查询出程咬金的薪水,第二部查询出薪水大于他的员工
select e.salary from  emp e where e.ename='程咬金';
select * from emp 
    where emp.salary>(select e.salary from  emp e where e.ename='程咬金');
*****************************************************************
-- 查询工资高于30号部门所有人的员工信息
-- 第一步查询出30号部门的最高工资,第二部查处大于最高工资的所有人信息
select max(salary) from emp where deptno=30;
select * from emp 
    where emp.salary>(select max(salary) from emp where deptno=30);
******************************************************************************
-- 查询工作和工资都与妲己完全相同的员工的信息
-- 第一步查询妲己的工作和工资,第二部查询相同的员工
select salary,job from emp where ename='妲己';
select * from emp
    where job=(select job from emp where ename='妲己')
    and salary=(select salary from emp where ename='妲己');
select * from emp 
    where (salary,job) in (select salary,job from emp where ename='妲己');
-- 利用99查询查询出共同的数据(salary,job相同)
select * from emp,(select salary,job from emp where ename='妲己') sj
    where emp.salary=sj.salary
    and emp.job=sj.job;
******************************************************************************
-- 查询有2个以上直接下属的员工信息
-- 对上级字段mgr进行统计,有2个相同说明,该编号所对应的人有2个直接下级
select mgr,group_concat(mgr),count(mgr) from emp group by mgr having count(mgr)>2;
select * from emp 
    where empno in (select mgr from emp group by mgr having count(mgr)>2);
*************************************************************************
-- 查询编号为7788的员工的名称,员工工资,部门名称,部门地址
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d 
    where e.deptno=d.deptno 
    and e.empno=7788;
***********************切记不可写成以下的形式*****************************
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d 
    where e.empno=7788;
总结:这是错误的,因为在进行多表查询的时候,没有写连接字段,肯定是错误的。

5.自连接

自己连接自己,起别名

-- 求7902的员工编号,姓名,经理编号,经理姓名
select mgr from emp where empno=7369;
select ename from emp where empno=(select mgr from emp where empno=7369);

select e1.ename,e1.empno,e2.mgr,e2.ename from emp e1,emp e2
    where e1.empno=e2.mgr
    and e1.empno=7902;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容

  • SQL语言基础 本章,我们将会重点探讨SQL语言基础,学习用SQL进行数据库的基本数据查询操作。另外请注意本章的S...
    厲铆兄阅读 5,320评论 2 46
  • MYSQL 基础知识 1 MySQL数据库概要 2 简单MySQL环境 3 数据的存储和获取 4 MySQL基本操...
    Kingtester阅读 7,809评论 5 116
  • 注:1.mysql是一种关系型数据库 2.大小写不敏感 3.字符串用单引号,若字符串里有单引号,则...
    孙浩j阅读 1,302评论 0 2
  • 问题1:char、varchar的区别是什么?varchar是变长而char的长度是固定的。如果你的内容是固定大小...
    风的低语阅读 1,169评论 0 8
  • 四哥发了一个微信“好男人装聋作哑,任女人唠叨不休“,我看了一下,没有回复,估计是跟四嫂又杠上了,没落到好果子吃。 ...
    米陌陌阅读 319评论 0 0