#1. 为什么需要数据库
只要是在客观世界存在的、可以被描述出来的都是实体
sa 账户属于SQL Server自带的超级管理员用户,新建用户名后应该把sa禁用或删除掉以保证服务器的安全
一个数据库至少包含一个数据库文件和一个事务日志文件
###需求说明:
如果因为删除数据而导致数据库空间空闲太多的情况,这可以就需要减少分配给数据库文件和事务日志文件的磁盘空间以免浪费磁盘空间。
如果要移动数据库到其它服务器上的时候可以使用分离和附加数据库
为防止数据丢失或损坏我们可以定期备份数据库,以便在需要的时候还原
为了实现数据完整性,需要检验数据库表中的每行和每列数据是否符合要求 在创建表的时候,应该保证以后的数据输入是正确的,错误的数据不允许输入
不同的字段需要设置为各种合适的类型,比如年龄就是整数类型
请大家思考 电话号码、性别、工资分别应该用什么数据类型存储?
通过指定一些表达式从而让列的值符合某个定义
规定学生年龄必须大于0岁并且少于100岁
默认值是指如果用户没有指定值的情况下会记录的此字段指定一个提供一个预先设定的值
可以把居住地默认值设置为北京
我们可以指定某个字段不能不输入,必须提供一个非空的值
姓名字段不能为空
表中一列或者几列组合的值能用来唯一标识表中的每一行,这样的列或者列组合称为表的主键,主键表的数据不同重复。
如果两列或者多列组合起来唯一标识表中的每一行,则该主键又称为"组合键"
主键的选择标准
学生的身份证号可以设置为唯一约束
思考: 如果标识列id的初始值为1,增长量为3,则输入3行数据以后,再删除1行,下次再输入数据行的时候,标识值自动插入的值是多少?
一个表的外键必须引用另一个表的主键,比如成绩表中的学生ID会引用学生表的主键,课程ID会引用成绩表的主键
use studb;
go
create table student
(
id int not null identity(1,1),
name varchar(10),
birthday datetime
)
alter table student add idcard varchar(15)
alter table student alter column idcard(18)
alter table student drop column idcard;
主键约束
alter table student add constraint pk_idcard primary key(id)
唯一约束
alter table student add constraint uq_idcard unique(idcard)
默认约束
alter table student add constraint df_address default('地址不详') for address
检查约束
alter table student add constraint ck_score check(score between 0 and 100)
外键约束
alter table score add constraint fk_sid foreign key(sid) references student(id)
删除约束
alter table student drop constraint df_address
Structured Query Language:结构化查询语言
主要的命令有CREATE
、ALTER
、DROP
等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用
它们是SELECT
、UPDATE、
INSERT、
DELETE`,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言
是用来设置或更改数据库用户或角色权限的语句,包括(grant
,deny
,revoke
等)语句
是一种符号,它是用来进行列间或者变量之间的比较和数学运算的
运算符 | 说明 |
---|---|
+ | 加运算,求两个数或表达式相加的和,如1+1 |
- | 减少减运算,求两个数或表达式相减的差,如4-1 |
* | 乘运算,求两个数或表达式相乘的积,如2*2 |
/ | 除运算,求两个数或表达式相除的商,如6/4的值为1 |
% | 取模运算,求两个数或表达式相除的余数,如:6%4的值为2 |
运算符 | 说明 |
---|---|
= | 把一个数或变量或表达式赋值给另一变量,如:name='zhufengpeixun' |
运算符 | 说明 |
---|---|
AND | 当且仅当两个布尔表达式都为true时,返回TRUE |
OR | 当且仅当两个布尔表达式都为false,返回FALSE |
NOT | 布尔表达式的值取反 |
运算符 | 说明 |
---|---|
= | 等于 |
> | 大于 |
< | 小于 |
<> | 不等于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于 |
INSERT [INTO] 表名 [(列名)] VALUES (值列表)
INSERT INTO [school].[dbo].[student]
(name,idcard,age,city)
VALUES
('欧阳锋','410787',30,'白驼山')
GO
通过SELECT INTO语句将现有表中的数据添加到新表中
SELECT (列名) INTO <表名> FROM <源表名>
SELECT id,name,idcard,age,city
INTO student_bak
FROM student
注意: 此语句只能执行一次
将现有表中的数据添加到已存在的表中
INSERT INTO <表名>(列名) SELECT <列名> FROM <源表名>
INSERT INTO student_bak
SELECT name,idcard,age,city
FROM student
注意: student_bak 表必须预先建立好,并且有对应的列名
更新表中的数据
UPDATE 表名 SET 列名 = 更新值 [WHERE 更新条件]
UPDATE [school].[dbo].[student]
SET age = 40,city = '上海'
WHERE id=7
注意: 更多多列时用逗号隔开,一定要加更新条件以免错误更新
id=7 and idcard='410787'
email is null or email = ''
删除表中的数据
DELETE [FROM] 表名 [WHERE <删除条件>]
DELETE FROM [school].[dbo].[student]
WHERE IDENT_CURRENT=7
Delete语句是对整行进行操作,因此不需要提供列名 如果要删除主表数据,则要先删除子表记录
截断整 个表中的数据
TRUNCATE TABLE 表名
TRUNCATE TABLE student
数据全部清空,但表结构、列、约束等不被改动 不能用于有外键约束引用的表 标识列重新开始编号 因为要删除的数据不会写入日志,数据也不能恢复,所以工作中请尽量不要使用此命令
SELECT <列名>
FROM <表名>
[WHERE <查询条件表达式>]
[ORDER BY <排序的列名>[ASC或DESC]]
SELECT id,name,idcard,age,city
FROM student
WHERE home= ‘北京’
ORDER BY id asc
SELECT id,name,idcard,age,city AS home
FROM student
WHERE city= '山东'
ORDER BY id asc
SELECT id,name,age,home=province+city
FROM student
WHERE city= '济南'
ORDER BY id asc
SELECT id,name,age,city
FROM student
WHERE city is null or city =''
SELECT id,name,age,city,'中国' as country
FROM student
SELECT top 2 id,name,age,city,'中国' as country
FROM student
SELECT top 20 PERCENT id,name,age,city,'中国' as country
FROM student
按照一定的百分比返回查询行数可以得到表中大致有多少数据行
ORDER BY
select * from school.dbo.score order by grade asc;
select * from school.dbo.score order by grade desc;
select * from school.dbo.score order by course_id asc, grade desc;
update student set email = UPPER(email)
select level from stu
order by
convert(int,left(level,CHARINDEX('-',level)-1)),
convert(int,right(level,LEN(level)-CHARINDEX('-',level))) desc
select * from school.dbo.student
where DATEDIFF(YY,birthday,GETDATE())>=18
select *from school.dbo.student
where DATEPART(M,birthday)=9 and province = '山东省'
select * from school.dbo.student
where DATEPART(D,birthday) = DATEPART(D,GETDATE())
select RIGHT(email, LEN(email) - CHARINDEX('@',email) )
from school.dbo.student where id=3
就是查询的条件是模糊的,不是特别明确的
代替一个或多个真正的字符,与LIKE 关键字一起使用
查询某一列在指定的规范内的记录,包括两个边界
select * from score where grade between 80 and 100
查询某一列中的值在列出的内容列表中
select * from student where city in ('北京','上海','广东')
对一组值进行计算,并返回计算后的值,一般用来统计数据
累加所有行的值
计算ID=1的学生的的总分
select SUM(grade) as '总分' from score where student_id = 1;
计算所有行的平均值
计算ID=1的学生的的平均分
select AVG(grade) as '平均分' from score where student_id = 1;
计算所有行的平均值
计算ID=1的学生的的平均分
select AVG(grade) as '平均分',MAX(grade) 最高分,MIN(grade) 最低分 from score where student_id = 1;
计算所有行的平均值
select AVG(grade) as '平均分',MAX(grade) 最高分,MIN(grade) 最低分 from score where student_id = 1;
计算学生总数
select COUNT(*) from student;
分组查询就是按某列的值进行分组,相同的值分成一组,然后可以对此组内进行求平均、求和等计算
SELECT FROM <表名>
WHERE <条件>
GROUP BY <分组字段>
SELECT列表中只能包含:
select student_id,avg(grade) from score group by student_id;
select course_id,max(grade) 平均分 from score group by course_id order by max(grade) desc
统计各省的男女同学人数-多列分组
select province,gender,COUNT(*) from student group by province,gender
SELECT FROM <表名>
WHERE
GROUP BY
HAVING
WHERE用于过滤掉不符合条件的记录
select province,COUNT(*) from student group by province having COUNT(*)>1
select DATEDIFF(dd,birthday,GETDATE())/365 from student
select student_id,COUNT(*) 不及格次数 from score where grade <60 group by student_id having COUNT(*)>1
多表联接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征
内联接就是通过比较运算符匹配两个表中的列值
语法
SELECT
FROM 表1
INNER JOIN 表2
ON 表1.字段1 = 表2.字段2
INNER JOIN 关键字后面是关联表,ON关键字后是表间联接字段的关系
select student.name,course.name,grade from student inner join score on student.id = score.student_id inner join course on score.course_id = course.id; ```
左外联接是以左表为基础的,左表的记录将会全部表示出来,而右表只会显示符合搜索条件的记录。右表记录不足的地方均为NULL
右外连接的原理与左外连接相同,右表逐条去匹配记录;否则NULL填充