Bootstrap

C# 数据库(一)sql server

课程:引用:11_01-三范式_哔哩哔哩_bilibili

C#编程-Winform基础和ADO.NET-CSDN博客    ADO.NET语言

一、SQL SERVER

1、基本操作

1.1、数据库基本操作

创建数据库

if exists(select*from sys.databases where name ='DBTEST')
    drop database DBTEST

-- 创建数据库
create database DBTEST
on  -- 数据文件
(
  name ='DBTEST',  --逻辑名称
  filename ='E:\SoftStudy\C#\C#\数据库\data\DBTEST.mdf',  --物理路径和名称
  size =5MB,  --  文件得初始大小
  filegrowth = 2MB--  文件增长方式可以写大小,也可以写百分比


)
log on  --日志文件
(
  name ='DBTEST_log',  --逻辑名称
  filename ='E:\SoftStudy\C#\C#\数据库\data\DBTEST_log.ldf',  --物理路径和名称
  size =5MB,  --  文件得初始大小
  filegrowth = 2MB--  文件增长方式可以写大小,也可以写百分比

)

1.2、建表

if exists(select*from sys.object where name = 'Department' and type = 'U')
    drop table Department
create table Department
(
    --部门编号,primary key:主建,identity(1,1):自动增长,初始值1,增长补偿1
DepartmentId int primary key identity(1,1),
--部门名称
DepartmentIdName nvarchar(50)  ,
--部门描述
DepartmentRemark text
)

1.2.1、建表基础、外键约束

外键。约束

if exists(select*from sys.objects where name='Department' and type='U')
    drop table Department
create table Department
(
    --部门编号  ,primary key :主建,identity(1,1):自动增长,初始值1,增长步长1
	DepartmentId int primary key identity(1,1),
	--部门名称
	DepartmentIdName nvarchar(50)  not null,
	--部门描述
	DepartmentRemart text

)
--char:定长,char(10) ,无论存储数据是否真的到了十个字节,都要占用10个字节
--varchar :变长, varchar(10) ,最多占用10个字节
-- varchar(10)  存储‘ab' ,占用2个字节
--text :长文本
--char, varchar ,text 前面加 n :存储unicode字符,对中文友好
--varchar(100):存储100个字母或者150个汉字
--nvarchar(100):存储100个字母或者100个汉字
create table [Rank]
(
    --职级编号  ,primary key :主建,identity(1,1):自动增长,初始值1,增长步长1
	RankId int primary key identity(1,1),
	--职级名称
	RankIdName nvarchar(50)  not null,
	--职级描述
	RankRemart text

)

--  员工表
create table People
(
    --部门
    PeopleId int primary key identity(1,1),  --员工编号
	DepartmentId int references Department(DepartmentId) not null, --  部门,已有的部门编号 (引用外键)
	RankId int references [Rank](RankId),      --  职级  (引用外键)
	PeopleName nvarchar(50) not null,
	PeopleSex nvarchar(1) check(PeopleSex='男' or PeopleSex='女') not null,
	PeopleBirth smalldatetime not null,
	PeopleSalary decimal(12,2) check(PeopleSalary>=1000 and PeopleSalary<=10000) not null,
	PeoplePhone varchar(20) unique not null,  --电话
	PeopleAddress varchar(300),   --  地址
	PeopleAddTime smalldatetime   default(getdate()) -- 添加时间


)

上代码 外键约束:

check约束

1.2.2、修改表结构列结构

1.3、alter表结构增添加约束

添加列

删除列

修改列

添加字段

添加约束

添加约束

--  修改表结构
--(1) 添加列
--after table 表名 add 新列名 数据结构
--给员工添加一列邮箱

alter table People add PeopleMail varchar(200)

--(2) 删除列
--alter table 表明 drop column 列名
--删除邮箱这一列
alter table People drop column PeopleMail

--(3)修改列
--  alter table 表名 alter column 列名 数据类型
alter table People alter column PeopleAddress varchar(200)

-- 维护约束(删除,添加)
--删除约束
-- alter table 表名 drop constraint 约束名
-- alter table People drop constraint 
-- 添加约束
-- alter table People add constrain 约束名 check(表达式) 在
alter table People drop constraint CK__People__PeopleSa__6FE99F9F
--alter table People drop constraint CK__People__PeopleSa__4D94879B
alter table People add constraint CK__People__PeopleSa1 check(PeopleSalary>=1000 and PeopleSalary<=1000000)

--主键约束
-- alter table People add constrain 约束名 primary key(列名)
--唯一约束
-- alter table People add constrain 约束名 unique(列名)
--默认值约束
-- alter table People add constrain 约束名 default 默认值 for 列名
--外键约束
--alter table 表名 add constraint 约束名 foreign key(列名)
references 关键表名(列名(主键))

1.4、向表中插入成员

--向部门插入数据
insert into Department(DepartmentName,DepartmentRemark)
values('市场部','......')
insert into Department(DepartmentName,DepartmentRemark)
values('软件部','......')
insert into Department(DepartmentName,DepartmentRemark)
values('企划部','......')

--简写
insert into Department values('硬件部','......')

--一次性插入多行
insert into Department(DepartmentName,DepartmentRemark)
select '测试部1','......' union   --union 把2两行连接
select '测试部2','......' union
select '测试部3','......'

--
insert into [Rank](RankIdName, RankRemark)
values('初级','......')
insert into [Rank](RankIdName, RankRemark)
values('中级','......')

insert into [Rank](RankIdName, RankRemark)
values('高级','......')



--  向员工表拆入数据
insert into People(DepartmentId,RankId,PeopleName,PeopleSex,PeopleBirth,PeopleSalary,PeoplePhone,PeopleAddress)
values(1,1,'刘备','男','1997-01-07',10000,'18845167963','中国')

1.5、修改删除数据

--修改
--语法
--  update 表名 set 字段1=值,字段2=值2 where 条件
-- 工资调整 每人加薪1000
update People set PeopleSalary=PeopleSalary+1000

--将员工编号为7加100
update People set PeopleSalary=PeopleSalary+500 where PeopleId=3

--将软件部(部门标号1)人员工资低于15000调整为15000
update People set PeopleSalary=1200  where DepartmentId=8 and PeopleSalary<10000


--删除
--语法
--delete from 表名  where
--删除所有员工  delete from People
-- truncate table table People  --删除数据,表结构依旧存在

--删除市场部工资大于10000得
--delete from People where DepartmentId=3 and PeopleSalary>10000

--drop table People  --把表都删除了
--truncate清空所有数据,不能有条件,delete 可以有条件删除,删除符合条件得数据
--使用truncate清空数据之后添加,编号仍然是1,2,3
--使用delete删除后,删除得编号就不存在了在之后添加数据,编号变成了6,7,8

1.6、查询数据

1.6.1、基础查询

select*from Department
select*from [Rank]
select*from People

--查询指定列(姓名,性别,生日,月薪,电话)
select PeopleName, PeopleSex ,PeopleBirth,PeopleSalary from People
--查询指定列(姓名,性别,生日,月薪,电话)
select PeopleName 姓名, PeopleSex 性别 ,PeopleBirth 生日,PeopleSalary 月薪  from People

--查询员工所在城市(重复得过滤掉)
select  distinct(PeopleAddress) from People 

--假设准备加工,查询出加工工资后得数据得员工数据
select*from People
select PeopleName 姓名, PeopleSex 性别 ,PeopleBirth 生日,PeopleSalary*1.2 月薪增加后  from People

1.6.2、条件查询

and 与or的区别

select*from People where PeopleSex='男' and PeopleSlary>=10000
--查询为女或者月薪大于一万

select*from People where PeopleSex='男' or (PeopleSlary>=10000 and PeopleSex='女')

1.6.3、条件查询二
--排序

--根据工资排序  asc升序默认,  desc降序
select*from People order by PeopleSalary desc
--根据名字长短排序
select*from People order by len(PeopleName) desc
--只取前面五个
select top 5*from People order by PeopleSalary desc
--查询工资最高百分之10
select top 10 percent*from People order by PeopleSalary desc
--null :空值


--查询80后的信息
--select * from People where PeopleVirth between '1980-1-1' and '1989-12-31'
--select * from People where PeopleVirth>='1980-1-1' and  PeopleVirth<='1989-12-31'
--select*from People shere year(PeopleBirth) between 1980 and 1989
--查询30-40岁之间,并且工资在15000-30000之间的 员工信息
--select * from People where year(PeopleBirth)>=30 and year(getdate())-year(PeopleBirth)<=40
--and (PeopleSalary>=15000 and PeopleSalary<=30000

--select * from People where (year(getdate())-year(PeopleBirth) between 30 and 40)  
-- and (PeopleSalary between 15000 and 30000)
--运算优先级

查询出  查询结果作为判断条件

--查询出星座是巨蟹座的员工信息
select * from People where (month(PeopleBirth)=6 and day(PeopleBirth)>=22) or (month(PeopleBirth)=7 and day(PeopleBirth)<=22)

--查询出工资比赵云高的人
--select * from People where PeopleSalary>(select PeopleSalary from People where PeopleName='赵云’

1.6、模糊查询

模糊关键字like 和通配符结合来实现


--模糊查询

--查出姓刘的员工信息
--select * from People where PeopleName like '刘%'  --查询出全部信息
--查询出名字含有 '刘' 的员工信息
--select * from People where PeopleName like '%刘%'  
--查询出名字含有 '刘' 或者'史'的员工信息
--select * from People where PeopleName like '%刘%'  or PeopleName like '%史%' 
--查出姓刘的员工 名字两个字
--select * from People where PeopleName like '%刘_' 
--从第几个字符取,取几个,索引从1开始
select SUBSTRING('hello world',3,1)
select * from People where  SUBSTRING(PeopleName,1,1)='刘' 
and len(PeopleName)=2

--查询名字组后一个字为香,名字一共三个字
--同上,查询电话号码开头为138的员工信息
--select * from People where PeoplePhone like '138%'
--同上,查询电话号码开头为138的员工信息,第四位为7或8,最后一个为5
--select * from People where PeoplePhone like '138[7,8]%5'
--查询电话号码开头为138的员工信息,第四位为7、8或9,最后一个不是2和3
--select * from People where PeoplePhone like '138[7,8,9]%[^2,3]'
--select * from People where PeoplePhone like '138[7-9]%[^2-3]'

1.7、聚合函数

聚合函数不应该出现在where里

select * from People
--求员工总人数
--select count(*) 人数 from People
--求最大值,求最高工资
--select max(PeopleSalary) 最高工资 from People
--求最小值,最小工资
--select min(PeopleSalary) 最低工资 from People
--求和,求所有员工的平均工资
select round(avg(PeopleSalary),2) 平均工资 from People

select round(25.555,2)
--求数量,最大值,最小值,总和,平均值,在一行显示
select count(*) 人数 ,max(PeopleSalary) 最高工资, min(PeopleSalary) 最低工资
,sum(PeopleSalary) 工资综合,round(avg(PeopleSalary),2) 平均工资 from People
where PeopleAddress='武汉'

--查询出武汉地区的员工人数,select round(25.555,2)
--求数量,最大值,最小值,总和,平均值,在一行显示
select count(*) 人数 ,max(PeopleSalary) 最高工资, min(PeopleSalary) 最低工资
,sum(PeopleSalary) 工资综合,round(avg(PeopleSalary),2) 平均工资 from People
where PeopleAddress='武汉'

--求出比平均工资搞得人数
select * from People where PeopleSalary>
(select round(avg(PeopleSalary),2) 平均工资 from People)

--求出数量,年龄最大值,年龄最小值,年龄总和,年龄平均值,在一行显示
--select *, year(getdate())-year(PeopleBirth) from People 
--select COUNT(*) 数量,
--max(year(getdate())-year(PeopleBirth)) 最高年龄,
--min(year(getdate())-year(PeopleBirth)) 最低年龄,
--sum(year(getdate())-year(PeopleBirth)) 总年龄

--from People

--方案二
--select DATEDIFF(YEAR,'1911-1-1','1993-3-3')
--select COUNT(*) 数量,
--max(DATEDIFFF(year,PeopleBirth,GETDATE()) 最高年龄,
--min(DATEDIFFF(year,PeopleBirth,GETDATE()) 最低年龄,
--sum(DATEDIFFF(year,PeopleBirth,GETDATE()) 总年龄

--from People



--求出月薪在1000以上的男性员工
--select DATEDIFF(YEAR,'1911-1-1','1993-3-3')
--select COUNT(*) 数量,
--max(DATEDIFFF(year,PeopleBirth,GETDATE()) 最高年龄,
--min(DATEDIFFF(year,PeopleBirth,GETDATE()) 最低年龄,
--sum(DATEDIFFF(year,PeopleBirth,GETDATE()) 总年龄

--from People
--where PeopleSalary>=10000 and PeopleSex='男'

-- 计算月薪在10000以上的男性员工的最大年龄,最小年龄和平均年龄
--求出月薪在1000以上的男性员工
--select '月薪1000以上' 月薪, '男',性别
--select COUNT(*) 数量,
--max(DATEDIFFF(year,PeopleBirth,GETDATE()) 最高年龄,
--min(DATEDIFFF(year,PeopleBirth,GETDATE()) 最低年龄,
--avg(DATEDIFFF(year,PeopleBirth,GETDATE()) 平均年龄

--from People
--where PeopleSalary>=10000 and PeopleSex='男'

上代码有逗号:

--求出数量,年龄最大值,年龄最小值,年龄总和,年龄平均值,在一行显示
--select *, year(getdate())-year(PeopleBirth) from People 
--select COUNT(*) 数量,
--max(year(getdate())-year(PeopleBirth)) 最高年龄,
--min(year(getdate())-year(PeopleBirth)) 最低年龄,
--sum(year(getdate())-year(PeopleBirth)) 总年龄

--from People

运行结果

1.8、分组查询

结果   group by

   having  count(*)>=2

--统计员工人数,员工工资总和,平均工资,最高工资和最低工资  武汉与北京
--方案一
--select count(*) 员工人数, sum(PeopleSalary) 工资总和, avg(PeopleSalary) 平均工资,
--max(PeopleSalary) 最高工资,min(PeopleSalary) 最低工资
--from People
--where PeopleAddress ='武汉'
--union   --连接作用, 要求两个查询结果列相同
--select count(*) 员工人数, sum(PeopleSalary) 工资总和, avg(PeopleSalary) 平均工资,
--max(PeopleSalary) 最高工资,min(PeopleSalary) 最低工资
--from People
--where PeopleAddress ='北京'

--方案二  group by
--select PeopleAddress 地区,count(*) 员工人数, sum(PeopleSalary) 工资总和, avg(PeopleSalary) 平均工资,
--max(PeopleSalary) 最高工资,min(PeopleSalary) 最低工资
--from People
--group by PeopleAddress


--统计员工人数,员工工资总和,平均工资,最高工资和最低工资  1985年以后不参与统计
--select PeopleAddress 地区,count(*) 员工人数, sum(PeopleSalary) 工资总和, avg(PeopleSalary) 平均工资,
--max(PeopleSalary) 最高工资,min(PeopleSalary) 最低工资
--from People
--whereBirth<'1985-1-1'
--group by PeopleAddress

--统计员工人数,员工工资总和,平均工资,最高工资和最低工资  1985年以后不参与统计,筛选出员工人数至少2以上
--select PeopleAddress 地区,count(*) 员工人数, sum(PeopleSalary) 工资总和, avg(PeopleSalary) 平均工资,
--max(PeopleSalary) 最高工资,min(PeopleSalary) 最低工资
--from People
--whereBirth<'1985-1-1'
--group by PeopleAddress
--having count(*)>=2


1.9、多表查询多表连接查询

1.9.1、简单多表查询

以上显示部门职级,三表显示

select * from People
select * from Department
select * from [Rank]

--笛卡尔乘积
select * from Department,People
--将查询结果将Department所有记录和People表所有记录依次排列组合成新的结果

--简单多条查询
--查询员工信息,显示部门信息
select * from People,Department
where People .DepartmentId=Department.DepartmentId
--查询员工信息,显示职级信息
--同上
select * from People,[Rank]
where People.RankId=[Rank].RankId


--三表查询
select * from People,[Rank],Department
where People.RankId=[Rank].RankId and  People .DepartmentId=Department.DepartmentId
1.9.2、内连接查询

两种方法查询区别

--简单多表查询和内连接共同的特点:不符合主外键关系的数据不会被显示出来

运行结果

--内连接查询

--查询员工信息,显示部门名称
select * from People
inner join Department on People.DepartmentId=Department.DepartmentId
inner join [Rank] on People.RankId=[Rank].RankId

1.9.3、外连接查询
1.9.3.1、左外连、

运行结果

--左外连:以左表为主表进行数据显示,主外键关系扎搜不到的数据用null取代

--外连接:  左外连、右外连、全外连

--左外连:以左表为主表进行数据显示,主外键关系扎搜不到的数据用null取代
--查询员工信息,显示部门名称
select * from People
left join Department on People.DepartmentId=Department.DepartmentId
select * from Department
left join People on People.DepartmentId=Department.DepartmentId

1.9.3.2、右外连
--查询员工信息,显示部门名称,下面两个效果一样
select * from People
left join Department on People.DepartmentId=Department.DepartmentId
select * from Department
right join People on People.DepartmentId=Department.DepartmentId

--右外连:以右表为主表进行数据显示,主外键关系扎搜不到的数据用null取代

运行结果

1.9.3.3、全外连

1.10、总结

当部门右软件部1、软件部2时候

having  修饰

根据部门、职级分组

1.10.1、自连接(自己连接自己)

;