diff --git "a/26\345\210\230\350\213\217\350\220\214/\346\225\260\346\215\256\345\272\223\347\254\224\350\256\260.md" "b/26\345\210\230\350\213\217\350\220\214/\346\225\260\346\215\256\345\272\223\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..0fb9afb8bac1d5d521a4b488e1a721a9da36d569 --- /dev/null +++ "b/26\345\210\230\350\213\217\350\220\214/\346\225\260\346\215\256\345\272\223\347\254\224\350\256\260.md" @@ -0,0 +1,501 @@ +## 数据库笔记 + +#### 一.创建数据库/使用数据库/创建数据表: + +```sql +--创建数据库 +--create database 数据库名称; +--使用数据库 +--use 数据库名称 +--创建数据表 +--create table 数据表名( +--列名1 数据类型 (约束) +--列名2 数据类型 (约束) +--列名3 数据类型 (约束) +--); +``` + +##### 1.表的属性: + +```sql +--表的属性 +--1.主键:primary key +--作用:唯一识别表中的一条记录,插入数据时,主字段不能为空并且不能重复 + +--2.自增属性:identity(自增起始值,自增步长) +--作用:系统帮忙计算插入自增字段的值 + +--3.唯一:unique 插入的值不能重复 + +--4.非空:not null 插入的数据不能为空值 + +--5.默认值:default 插入的数据没有值时,系统默认帮忙设置的值 + +--6.检查:check(条件语句) + +--7.外键:foregin key (本表外键字段) reference 参照表名称(参照表字段) +``` + +##### 2.删除数据库/数据表/修改数据表 + +```sql +--1.删除数据库 +drop database 数据库名称 +--注意:当数据库正在使用无法删除时,先切换到master,再删除 + +--2.删除数据表 +drop table 数据表名称 + +--3.修改数据表 +alter table 数据表名称 +alter column 列名 要修改的数据 + +``` + +##### 3.数据类型 + +```sql +--数据类型 + 整型:int + 字符串型:nvarchar(10),varchar(10),text + 浮点型:float,decimal(n,m) + 注:'n'代表数值的总位数,'m'代表小数的位数 + 货币:money + 日期:date,time,datetime +``` + +#### 二.修改表的结构 + +```sql + --修改表的结构 + --1.增加字段 + alter table 表名 + add 字段名 数据类型 (约束) + --2.删除约束 + alter table 表名 + drop constraint 约束名 + --3.删除字段 + alter table 表名 + alter column 列名 + --4.修改字段的数据类型 + alter table 表名 + alter table 字段名称 数据类型 + --注:修改表名:exec sp_rename '旧表名','新表名' + --修改表的字段名:exec sp_rename '表名.旧字段名','新字段名' +``` + + + +##### 1.约束: + +```sql + --默认约束: + alter table 表名 + add constraint DF_表名_字段名 (约束) for 字段名 + + --主键约束: + alter table 表名 + add constraint PK_表名_字段名 (约束) +``` + +##### 2.插入/删除/修改数据: + +```sql + --1.插入数据: + insert into 表名/(列名1,列名2,....) + values (值1,值2,....),值1,值2,....), + --注:列名和值:数量 数据类型,顺序一一对应 + --列名的列表可以省略,所有字段(除自增字段)按顺序插入值时可以省略 + + --2.删除数据:(‘delete’只删除数据,不删除表,自增值从上一次自增后的值开始) + delete from 表名 where 删除条件的表达式 + truncate table 表名 --整张表删除重建,自增重新从起始值开始 + + --3.修改数据: + update 表名 set 列名=更新后的值,列名=更新后的值,... + where 修改的条件表达式 +``` + +### 三.数据的查询 + +##### 1.查询单表的所有数据: + +```sql +select * from 表名 + --‘*’指表中的所有列,‘from’指要查询的表 +``` + +##### 2.查询指定列 + +```sql + 语法:select 列名1,列名2,.... from 表名 + + --给列名设置别名 + 1)列名 别名 + 2)列名 as 别名 + 3)别名=列名 +``` + +##### 3.只查询若干行 + +```sql + top:获取查询结果的前几行 + --查询信息表中的前几(n)行 + select top n * from 表名 + --获取信息表的 n% + select top n percent * from 表名 + --查询信息表中具体哪几列 + select 列名1,列名2,... from 表名 +``` + +##### 4.查询结果去除重复项 + +```sql +distinct:不同的 + select distinct 列名1,列名2,... from 表名 +``` + +##### 5.对查询结果进行排序 + +```sql +order by 排序字段 asc升序 desc降序 + select * from 表名 order by 列名 asc/desc + --注:select * from 表名 order by 列名 (默认升序) +``` + +#### 三:where条件表达式 + +```sql + --运算符 + --(1)比较运算符:>、>=、<、<=、<>、!= + --(2)逻辑运算符:and 与、or 或、not 非 + --(3)范围运算符:between A and B ,在[A,B]范围内 + -- not between A and B ,不在[A,B]范围内 + --(4)列表运算符:in (值1,值2,...) not in (值1,值2,...) + --(5)空值运算符:is null 值为 null 返回结果记录 + -- is not null 值不为 null 返回结果记录 + --“null”:插入数据时,没有给该字段赋值,也没有指向内存空间的地址 + --’‘:空字符,没有任何字符,有储存空间 + --(6)模式匹配运算符:like’模式字符串‘ + -- 匹配字符:%:匹配 0-n 任意字符 + -- _:匹配1个任意字符 + --eg:查询桂林市的学生信息 + select * from 表名 where 列名 like '%桂林市%'; + --eg:查询姓刘的学生信息 + select * from 表名 where 列名 like '刘%'; + --eg:查询包含天字的学生信息 + select * from 表名 where 列名 like '%天%'; + --eg:查询姓刘且名为2个字的学生 + select * from 表名 where 列名 like '刘_ _'; +``` + +#### 四.1 聚合查询 + +```sql +求总记录数,select count(0) from 表名 +求和,select sum(字段) from 表名 +求平均,select avg(字段) from 表名 +求最小值,select min(字段) from 表名 +求最大值,select max(字段) from 表名 +``` + +注:select 字句中有聚合函数,那么表的其他列名可以是 group by 子句后的分组字段,不能是其他非分组字段 + +#### 四.2分组查询 + +```sql +select 字段1, 聚合函数(字段2) from 表名 group by 字段1 +``` + +```sql +1. 字段1 表示需要分组的字段。 +2. 字段2 表示聚合函数需要的字段。 +``` + +注:‘where’ 条件语句放在 group by 之前 + +```sql +1. 'group by'字段:将数据进行按照分组字段进行分组,分组字段值相同分为同一组,聚合函数对该组数据进行统计计算,每一组返回统计结果值 +2.'having'子句:对查询处理后结果数据进行条件筛选,条件表达式允许有聚合函数,条件表达式中引用的字段只能是对分组字段 +3.'where'子句:对原始数据进行条件筛选,表达式中不允许有聚合函数 +``` + +```sql +select 列名... from 表名... where 条件表达式 group by 分组字段... having 条件表达式 order by 排序字段 +``` + +#### 四.3多表连接查询 + +SQL Server中连接查询分为如下几种: + +1. 内连接(inner join) +2. 左连接(left join) +3. 右外连接(right join) +4. 全外连接(full outer join) +5. 自连接 + +#### 1.内连接(inner join) + +##### 语法: + +```sql +select * from 表1 inner join 表2 on 表1.列 = 表2.列 +``` + +其中: + +```sql +1. inner join 是关键词。 +2. 表1和表2 就要是连接的两个表。 +3. on 后面表示通过哪个字段进行连接。 +``` + +内连接:只有显示两表连接条件匹配的记录行 + +##### 指定列 + +上面是获取两个表的所有信息,如果要取指定列,需要在列前加上表名: + +```sql +select 表1.列1,表1.列2,...,表2.列1,表2.列2,... from 表1 inner join 表2 on 表1.列 = 表2.列 +``` + +#### 2.连接多表 + +上面都是连接两个表,SQL Server中连接查询允许连接多个表,语法: + +```sql +select * from 表1 + inner join 表2 on 表1.列 = 表2.列 + inner join 表3 on 表2.列 = 表3.列 + ... +``` + +#### 内连接总结 + +语法: + +```sql +select 表1~N.列1~N,... from 表1 + inner join 表2 on 表1.列 = 表2.列 + inner join 表3 on 表2.列 = 表3.列 + ... + [where 条件] + [group by 字段] + [having 条件] + [order by 字段] +``` + + +#### 外连接 + +不仅仅返回连接列相等的记录,两表连接条件没有匹配的记录也可以返回 + +##### 1.左连接(left join) + +SQL Server除了内连接,还有左连接,语法格式同inner join,只是关键词替换为left join: + +```sql +select 表1~N.列1~N,... from 表1 + left join 表2 on 表1.列 = 表2.列 + left join 表3 on 表2.列 = 表3.列 + ... + [where 条件] + [group by 字段] + [order by 字段] + [having 条件] +``` + +##### 2.右连接(right join) + +右连接查询同左连接: + +```sql +select 表1~N.列1~N,... from 表1 + right join 表2 on 表1.列 = 表2.列 + right join 表3 on 表2.列 = 表3.列 + ... + [where 条件] + [group by 字段] + [order by 字段] + [having 条件] +``` + +#### 全外连接(full outer join) + +外连接实际上就是左连接和右连接综合: + +```sql +select 表1~N.列1~N,... from 表1 + full outer join 表2 on 表1.列 = 表2.列 + full outer join 表3 on 表2.列 = 表3.列 + ... + [where 条件] + [group by 字段] + [order by 字段] + [having 条件] +``` + +#### 自连接 + +自连接查询:如果在一个连接查询中,涉及到的两个表都是同一个表,这种查询称为自连接查询。 + +#### 五、子查询 + +是一个嵌套在select、insert、update或delete语句或其他子查询中的查询,任何允许使用表达式的地方都可以使用子查询 + +```sql +1.子查询作为虚拟表 select .. from (select .. from ..) '别名' +2.子查询作为列[只能返回一行一列] select 列1,(select...from...),列3 from ..... +3.子查询作为条件 + 1) 比较运算符连接条件 >=, <= , > ,< ,!= ,<> [子查询必须返回一行一列的值] + 2) in、not in连接条件 [in,not in子查询] [子查询结果集只能是一列] + 3) exists,not exists连接条件, + exists(select * from 表名......),select 子句有一行或以上的记录返回true,否则一条记录都没有返回false +4) any,all连接条件,any(和子查询返回的某个值比较),all(和子查询返回的所有值比较) +``` + +#### 六、分页查询 + +```sql +SQL Server中分页有三种方法: +1. offset +2. 子查询 +3. row_number +``` + +## offset + +语法: + +```sql +select 列名,..... from 表1 order by 字段 [asc | desc] +offset 偏移的行数 rows fetch next 要获取的行数 rows only +``` + +其中: + +```sql +1. order by 固定关键词,分页必须写。 +2. @Offset 表示偏移多少行。 +3. @Num 表示取几条记录。 +``` + +例如: + +```sql +--假设每页n条记录,那么请查询出第m页的数据 +select * from Student order by StudentId asc offset (页码m-1)*n rows fetch next n rows only +``` + +#### 子查询语法: + +```sql +select top N * from 表 where 表主键 not in (Select top M 表主键 from Student); +``` + +**示例**,假设每页2条记录,那么请查询出第4页的数据 + +```sql +select top 2 * from Student where StudentId not in (Select top 6 StudentId from Student); +``` + +通过上面我们可以发现,有一定的规律: + +```sql +select top 2 * from Student where StudentId not in (Select top (页码-1)*2 StudentId from Student); +``` + +#### row_number方法 + +row_number查询语法: + +```sql +select * from ( + select row_number() over(order by 字段 [asc|desc]) as RowId, 其他字段, ... from table +) as Temp where Temp.RowId between n and m; +``` + +```sql +规律: +select * from ( + select row_number() over(order by StudentId asc) as RowId, * from Student +) as Temp where Temp.RowId between (页码-1)*条目数+1 and 页码*条目数; +``` + +#### 七、日期函数 + +```sql +1.getdate() 获取当前系统时间 +2.year()函数截取时间的年份部分,返回的是整数类型 +3.month()函数截取时间的月份部分,返回的是整数类型 +4.day()函数截取时间的日期部分,返回的是整数类型 +5.datepart(指定日期部分,日期时间) 获取指定的日期部分,返回是一个整型;日期部分有年、月、日、周.................. +6.dateName(指定日期部分,日期时间) 获取指定的日期部分,返回是一个字符串类型;日期部分有年、月、日、周.................. +7.dateadd(指定日期部分,整数,日期时间) 将日期时间的指定部分增加上整数值,返回的是一个日期时间类型。 +8.datediff(指定日期部分,开始时间,结束时间) 将结束时间-开始时间,返回的是的指定日期部分的差值,是一个整数类型。 + +--查询当前时间 +select getdate() +--查询年份 +select year('2001-01-01') +select year(getdate()) +--查询月份 +select month(getdate()) +--查询日期 +select day(getdate()) +``` + +``` sql +1.datepart(指定日期部分,日期时间),返回的是一个整数 +2.datepart 日期部分代码缩写 +3.年 yy, yyyy,year +4.季度 qq, q,quarter +5.月 mm, m,month +6.年中的日 dy, y,day of year +7.日 dd, d,day +8.周 wk, ww,week +9.星期 dw, w,weekday +10.小时 hh,hour +11.分钟 mi, n,minute +12.秒 ss, s,second +13.毫秒 ms,millisecond +14.微妙 mcs +15.纳秒 ns + +select datepart(year,getdate()) 年份 --year年份 +select datepart(month,getdate()) 月份 --month月份 +select datepart(day,getdate()) 日期 --day日期 +select datepart(dayofyear,getdate()) 一年中的第几天 --day日期 +select datepart(weekday,getdate()) 星期数 --WEEKDAY 一周中的星期数;整数的星期,1代表星期日,2代表星期一,.........,7代表星期六 +select datepart(weekday,'2023-03-18') 星期数 +select datepart(weekday,'2023-03-19') 星期数 + +select datepart(week,getdate()) 一年中的第几周 --WEEK一年中的周数 + + + +--dateName(指定日期部分,日期时间),返回的是一个字符串 +select dateName(weekday,getdate()) 星期数 +select dateName(weekday,'2023-03-19') 星期数 + + +--日期增加函数,dateadd(指定日期部分,增加的整数值,要增加的日期时间) ,返回的是一个增加相应部分值的日期时间类型值 +select dateadd(year,10,getdate()) --距今10年后的时间 +select dateadd(month,10,getdate()) --距今10个月后的时间 +select dateadd(day,10,getdate()) --距今10天后的时间 +select dateadd(week,10,getdate()) --距今10周后的时间 + +--日期减法函数,datediff(指定日期部分,开始时间,结束时间),返回的是结束时间-开始时间的指定部分的差值,是一个整数类型 +select datediff(year,'2000-01-01',getdate()) +select datediff(month,'2000-01-01',getdate()) +select datediff(day,'2000-01-01',getdate()) + +--查询本月的第一天 +-- 1)用datediff函数获取今天距离日期起始值0的月份数;--0代表了数据库中起始日期值1900-01-01 +-- 今天的日期 - 1900-01-01 的月份差值 +select datediff(month,0,getdate()) +``` + + +