主键就是数据行的唯一标识。不会重复的列才能当主键。

主键有两种选用策略:业务主键和逻辑主键。业务主键是使用有业务意义的字段做主键,比如身份证号、银行账号等;逻辑主键是使用没有任何意义的字段做主键,完全给程序员看的,业务人员不会看的数据。因为很难保证业务主键不会重复、不会变化,因此推荐使用 逻辑主键。

外键:ForeignKey

数据类型:

bit 可选值为:0 1 对应C#中 bool false true

varchar(n) nvarchar(n) :可能含有中文的用nvarchar

char(n) : 不足长度n的部分用空格填充.不确定长度的时候用 varchar(n)

SQL语句是和DBMS“交谈”专用的语句,不同DBMS都认SQL语法。

SQL语句中字符串用单引号。

SQL语句是大小写不敏感的,不敏感指的是SQL关键字(表名,列名等),字符串值还是大小写敏感的。

创建表:create table T_Person

删除表:drop table T_Person

插数据:insert into T_Person(ID,Name,Age) values(1,'Jin',20)

SQL主要成分DDL(数据定义语言)和DML(数据操作语言)两类。Create Table、Drop Table、Alter Table 等属于DDL,Select、INsert、Update、Delete等属于DML

SQL中生成GUID的函数 select newid()

C# 中生成Guid的方法: Guid.NewGuid(),返回是Guid类型

int自增字段的优点:占用空间小、无需开发人员干预、易读

   缺点:效率低,数据导入导出麻烦

Guid的优点:效率高、数据导入导出方便;

缺点:占用空间大、不易读

--插入数据(如果插入的行中有些字段的值不确定,那么Insert的时候不指定那些列即可)

insert into Person(name,age) values('aa',38)

--给可以给字段默认值,如果Guid类型主键的默认值设定为newig()就会自动生成,很少这么做

insert into Person(id,name,age) values(newid(),'aa',38)

--更新数据

update Person set age=30 where name='Tom' or name='jack'

<>:不等于 !=

--删除数据

delete from Person where age>20

--查询数据

--检索不与任何表关联的数据:

select 1+1 as 列1,getdate() as 日期,newid() as 编号

--增加表的字段

alter table T_Employee add FSubCompany varchar(20)

as 起别名

select newid() as Guid编号

select FName as 姓名,FAge as 年龄,FSalary as 月薪 from T_Employee

--聚合函数 对数据进行统计的(不能出现在where语句中)

select count(*) from T_Employee

--一共有多少条数据

select max(FSalary) from T_Employee

--月薪最高的

select min(FSalary) from T_Employee

--月薪最低的

select avg(FSalary) from T_Employee

--平均月薪

select sum(FAge) from T_Employee

--年龄的和

--排序

select * from T_Employee order by FSalary

--按照月薪排序(默认由小到大) 

ASC  升序

DESC 降序

select * from T_Employee order by FSalary DESC,FAge ASC 先按FSalary,再按FAge

--order by

order by字句位于select语句的末尾,它允许指定按照一个列或者多个列进行排序,还可以制定排序方式是升序(从小到大排列,ASC)还是降序(从大到小排列,DESC)

order by字句要放到where字句之后

--通配符过滤like

单字符匹配:"_"

例如:以任意字符开头,剩余部分为"erry"的员工信息

select * from T_Employee where FName like '_erry'

多字符匹配(0个或多个):"%"

例如:检索姓名中包含字母"n"的员工信息

select * from T_Employee where FName like '%n%'

--空值处理

一个列如果没有指定值,就是null,表示"不知道",而不是没有。

select null+1 结果为null,因为"不知道"加1的结果还是"不知道"

select * from T_Employee where FName=null

没有任何返回结果,因为数据库也"不知道"

SQL中用 is null 、is not null 来进行空值判断

select * from T_Employee where FName is null;

--in

select * from Person where Fage=23 or Fage=25 or Fage=28

select * from Person where Fage in (23,25,28)

--between and

select * from Person where Fage>20 and Fage<30

select * from Person where Fage between 20 and 30

--数据分组 group by

select FAge,count(*) from T_Employee group by FAge --按照年龄分组统计出每个年龄的人数

没有出现在Group by子句中的列不能放到select语句后的列名列表中(聚合函数除外)

--错误例子 因为FSalary没有出现在group by 子句中

select FAge,count(*),FSalary from T_Employee group by FAge

--正确

select FAge,count(*),max(FSalary) from T_Employee group by FAge

--having语句 having是对分组后信息的过滤

在where语句中不能使用聚合函数 而应该用having 在having中出现的列必须包含在select中

select FAge,Max(FSalary),count(*) from T_Employee group by FAge

select FAge,Max(FSalary),count(*) from T_Employee

where count(*) > 1

group by FAge

--错误 因为聚合函数不能出现在 where 子句中

select FAge,Max(FSalary),count(*) from T_Employee

group by FAge

having count(*) > 1

--正确

select FAge,count(*) from T_Employee

where FSalary > 2000

group by FAge

--正确

select FAge,count(*) from T_Employee

group by FAge

having FSalary > 2000

--错误,having是对分组后信息的过滤,能用的列和select中能用的列是一样的

--having无法代替where。where是对原始数据进行过滤,having是对分组后的信息过滤

--限制结果集行数 (分页 Row_Number)

select top 3 * from T_Employee order by FSalary desc

select top 3 * from Person

where Fnumber not in(select top 5 Fnumber from Person order by Fsalary desc)

order by Fsalary desc

--distinct消除(整行的)重复的数据 如果有两行则只有两行数据完全一样时才消除

select distinct FSubCompany from T_Employee

select distinct FSubCompany,FSubDepartment from T_Employee