MYSQL
[语句不要拼错,表名、列名不要写错,语句难记要记住]
创建表
模版
create table 表名(列名1 数据类型 [约束],
列明2 数据类型 [约束],
[表级约束]);
约束
单一主码约束
primary key
联合主码约束
primary key(列名1,列名2) [要在列名12定义后,的单独表级约束]
外码约束
foreign key(当前列名) references 另一表名(参照列名)
如:sc表的 sno 引用student的外码(sno)
foreign key(sno) references student(sno)
cascade 级联
restrict 限制
on delete restrict 删除限制
on update cascade 更新级联
- 聪明的你自己写出:删除级联 ——————————
实战实例
sc表的 sno 引用Student的外码(sno),设置删除限制,更新级联
foreign key(sno) references student(sno) on delete restrict on update cascade
非空约束
not null
唯一约束
unique [允许有一个空值]
枚举类型
[有的版本不支持]
ENUM('男','女') [前面无需数据类型]
条件约束
列名 数据类型 check(列名=0)
默认取值
default 取的值 [前面需数据类型]
如: sdept varchar(20) default '计算机系'
自动增长列
auto_increment 一般是主键约束
数据类型
char(n) 字符型
varchar(n)可变长字符
int 整型
date 日期型
smallint
枚举类型建议一定是enum 且前面不需加数据类型
decimal(m,n) 数值型 m表示数据长度(整数位数+小数位数),n表示小数点后长度
修改表
模版
alter table 表名
[新加列]add 新列名 数据类型 [约束] //新增加一个列,
drop column 列名 //删除列,
[修改列常用]modify 待修改的列名 要修改的数据类型 //修改列的类型,
add column 列名 type 数据类型 //修改列的类型,
add foreign key(列名1) references 表名(列名2) on delete cascade,
rename column 旧列名 to 新列名 //修改列名;
增加自动增长列
alter table 表名 add column 列名 数据类型 auto_increment
实例:
alter table spj add column id int PRIMARY KEY auto_increment;
当一个select 要修改多个时候,多个语句要加逗号隔开,
或多个select 多次修改[考试禁用,因为考试时只能一条语句]
修改职工表emp:
增加列:部门编号:dno char(3) ,设置外码约束参照部门表dept的dno,并设置删除和更新均为级联。
alter table emp add column dno char(3) , add FOREIGN KEY (dno) REFERENCES dept(dno) ON DELETE CASCADE ON UPDATE CASCADE;
查询表
模版
select 输出的列名1,输出的列名2
from 表名1,表名2
[以下皆可选,但相对顺序要与下面一致]
where [条件]
group by [分组]
having [条件]
order by [排序]
limit [限制输出行数]
tips
`` 可以用重命名 [esc下面那个键]
多个表起 别名
多个列加 表名.
select
select *
[选择所有列的所有行]
select 列名1,列名2,'hello'
还可以乱入一列全是hello的列[列名也是hello 这样毫无意义]
一般在后面加as 取别名(别名最好''引用起来) 或直接不加as
select sno,sname,'hello' as comment from student select sno,sname,'hello' comment from student
select 计算表达式
要求输出出生年份,但表中只给了年龄
select 2024-age [更标准用函数获取今年年份]
current_date() //返回当前日期 格式2024-10-29 实战直接用curdate() 一样效果
year(date) 提取年份 如:year('2024-10-22') =2024 延伸月、天等也可以
select year(current_date())-age
select 2+5 输出一列7
select concat(列名1,列名2,'我是聪明蛋')
把列1和列2 合并成一列输出 [不只是列,还可以乱入任意字符]
select name as 'office-name',concat(province ,address) as 'office-address' from office
select group_concat([distinct] 列名 [order by] separator '分隔符')
这个语句一般要分组使用,或者只有一行也行
将多个行中的字段 连接起来,以一个列表输出,按排序规则,以分隔符隔开,选择去重
select dept_id,GROUP_CONCAT(DISTINCT job_title order by job_title SEPARATOR ',') from employee where dept_id=1000
group_concat(distinct exp order by separator '')
distinct 可选,去重
exp 行名
order by 列表内容排序规则
separator 以什么东西分隔开
返回一个列表,即字符串列表
select 函数
round(grade) 取整数
round(grade , 2) 取两位小数
count()
count(*) 返回NULL和非NULL的行数,即所有行。
count(exp) 返回exp为非NULL的行数。
count(distinct exp) 返回exp无重复且非NULL的行数。
AVG() :[平均值]只适用于数值类型的字段或变量。不包含NULL值
SUM() :[取和]只适用于数值类型的字段或变量。不包含NULL值
MAX() :[最大值]适用于数值类型、字符串类型、日期时间类型的字段(或变量)不包含NULL值
MIN() :[最小值]适用于数值类型、字符串类型、日期时间类型的字段(或变量)不包含NULL值
from
from 单个表名
from 表名1,表名2
from 表名1,(select------) as 表名2 [派生表2]
其中多表联合一般都可以用如下解决,不必思考其他[太麻烦了,看不懂,记不清,且没遇到过必须用的]
from b1,b2
where b1.sno= b2.sno
where
后面加的是表中出现的列的有关条件
where 后面一般是表中列名符合什么什么条件
like 字符串模糊匹配
like '%数据%'
%任意数量字符
_单个字符
where sname not like '张%';//不姓张 where product_name like '%联想%'//名称出现联想
空值
is NULL 是NULL
is not NULL 不是NULL
in ()
存在于括内列表内
not in ()表示不存在
一般在in 前还要加一个变量如 sno in()
SELECT * FROM employee WHERE job_title IS NULL OR job_title NOT IN ( '总经理', '经理' );
group by
加一个表中变量,且这个变量是唯一的,无重复值[有重复,两个组就一样了,还分个蛋组]
如:group by sno
having
对分组后结果 再次进行条件查询
多加上count()语句
查询统计学生不及格(低于60分)门数大于等于2门的信息,输出系名,学号,姓名,不及格门数,按照系(升序)排序,不及格门数(降序)排序
select sdept,sc.sno,sname,count(*) from student,sc where student.sno=sc.sno and grade<60 group by sno having count(*)>=2 order by 1 asc,4 desc
order by
asc 升序[默认]
desc 降序
单一排序规则
列名 desc/asc [还可以直接把列名换成select 输出的第几个列]
联合排序规则
列名1 desc ,列名2 asc [逗号]
limit
limit +n 只输出前n行信息
limit n,m 从第n+1条记录开始,返回m条记录
limit 1,4 是2-5
union
把两个表结果连接起来,要求两个表结构一样[列数等等]
select distinct bno as No,bname as Name,'图书' as Type from book union select distinct cno as No,name as Name,'学生'as Type from card
高阶查询
在where后的嵌套查询
in
select * from student where sdept in (select sdept from student where sname='王大力')
借用select 查询返回的集合
没有同时选修“计算机导论”和“计算机网络”两门课的学生的学号,姓名
也就是 不是都有这两门课
select sno,sname from student where sno not in (select sno from course,sc where course.cno=sc.cno and cname='计算机导论' and sno in (select sno from course,sc where course.cno=sc.cno and cname='计算机网络'))
not exists
查询选修了全部课程的学生的学号,姓名,系名
(不是非常懂,不分析了,暂时记住模版吧)
理解就是从第一个表也就是student的每一行执行后面语句,得到true就输出,否则下一行继续
student的一行拿到与第二个表course 的每一行一个一个比对,执行下面,也就是sc表
第三个表中一个一个执行两个比较语句[course.cno=sc.cno and sc.sno=student.sno)] ,其中如果一个学生没有选那门课就会false ,第二个not exists 会是一个非空集,然后第一个not exists 会是一个空集,就不输出。
以上纯属瞎扯
第一个select 输出的列
第二个select条件(全部课程)
第三个select 两个等于
select sno,sname,sdept from student where not exists (select * from course where not exists ( select *from sc where course.cno=sc.cno and sc.sno=student.sno))