/*1. 可利用的资源*/
-- 帮助手册
-- AdventureWorks
-- 创建数据库
-- create database StudentManager
-- 如何学习创建数据库 点击一个已经创建好的数据库,右键 编写数据库脚本 到 新建查询,就会出现编写数据库的脚本。
/*
CREATE DATABASE [StudentManager] ON PRIMARY
( NAME = N'StudentManager', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\StudentManager.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'StudentManager_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\StudentManager_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
COLLATE Chinese_PRC_CI_AS
GO
*/
--删除数据库
--DROP DATABASE [Student Manager]
/*
如何设计数据库表
学生管理系统,学生信息(编号,姓名,性别,出生日期),课程信息(课程编号,课程名称),学生可以选择课程,
我们可以给学生一个分数。
*/
/*
概念萃取
名词和动词
名词:学生信息(编号,姓名,性别,出生日期) , 课程信息(课程编号,课程名称)
动词:选择课程(选课)分数
*/
/*
绘制ER图
矩形===》实体
椭圆===》属性
菱形===》关系
元:关系链接实体的个数 一元关系,二元关系,多元关系
映射基础:m:n
*/
/*
转换成表
1. 如果是m:n的关系,实体转换成表,关系也转换成一张表,并且将两端实体的主键拿过来做关系的外键,同时构成该表的复合主键.
2. 如果是1:n的关系,实体转换成表,关系不转换成表,我们将1端实体的主键,拿过来过N端实体外键
3. 如果是1:1的关系,实体转换成表,关系不转换成表,我们将任意一端实体的主键,作为另外一端实体的外键
*/
/*
课堂作业:
旅游公司 可以组团进行旅游(公司编号,组织机构代码,公司名字)
1个导游(导游编号,导游姓名)可以导很多条路线(路线编号,路线),一个路线可以被很多导游导。
一个导游可以从属于N个旅游公司。导游的线路属于某一个公司,一个公司有多条线路。
名词:旅游公司 , 导游 , 路线
动词:公司管理导游 导游导路线
*/
/*
范式:第一范式(课后思考),第二范式,第三范式
第二范式:不存在局部依赖
第三范式:不存在传递依赖
A决定B,我就说B依赖于A
第三范式:
学生信息(编号,姓名,性别,出生日期,班级编号,班级名称)
1001 张三丰 男 1919-5-4 1 一班
1002 张四丰 男 1919-5-5 1 二班
修改如下:
编号,姓名,性别,出生日期,班级编号
班级编号,班级名称
1001 张三丰 男 1919-5-4 1
1002 张四丰 男 1919-5-5 1
1 二班
课下作业:第一范式的准确概念
*/
/***********************第二天****************************/
/*
1. 数据类型
F1 ---> 输入数据类型
1.1 精确数字
int 4字节32位 -2的(32-1)的次方 ~ 2的(32-1)的次方-1
decimal 小数 numeric(p [, s]) numeric(4)或者numeric(4,3)
numeric(4,1) ==> 999.9
tinyint [0-255]
bit : 0 , 1 ==> 如果我向里面存储一个2, 不会报错,存储进去是1 ,非0即真
import : int numeric bit
1.2 日期类型
datetime 1753年开始的
1.3 字符串
char和varchar的区别:
char:定长
varchar:可变长度
name char(8) 张三 : 并不是占了4个字节,而是固定长度8个字节 最多8000个字节
name varchar(8) 张三: 他占4个字节
text : 取值范围特别大,最大长度为 2^31-1 (2,147,483,647) 个字符
char和nchar区别:
name char(4) : 张三丰
name nchar(4)
: ABCDF unicode编码的
1.4 二进制
密码 文件 图像存储
1.5 uniqueidentifier类型
可以作为表的主键,但是,他只能做小表(表比较小,数据比较少),如果是大型的表或者数据比较多的情况下,速度慢。
*/
/*
创建表
*/
create table S
(
SID int ,
SName varchar(10),
SSex char(2),
SBirthday datetime,
SAddress nvarchar(100),
SStatus bit
)
GO
insert into S values( 1001 , '张三丰' , '男' , '1989-01-01' , '五台山' , 1 )
select * from S
-- 删除表
drop table S
/*
约束种类
一、主键约束
二、不能为空约束
三、检查约束
*/
create table S
(
SID int primary key , -- PK 主键
SName varchar(10) not null, -- 不能为空约束
SSex char(2) check ( SSex in ( '男' , '女' ) ) , -- 必须存储 男或者女 检查约束
SBirthday datetime,
SAddress nvarchar(100),
SStatus bit
)
GO
insert into S values( 1001 , '张三丰' , '男' , '1989-01-01' , '五台山' , 1 )
insert into S values( 1002 , '杨玉环' , '女' , '1989-01-01' , '感恩寺' , 1 )
/*
四、唯一约束
*/
create table C
(
CID int identity(1,1) primary key,
CName varchar(100) unique
)
insert into C values('高等数学')
insert into C values('数据结构')
select * from C
/*
PK(SID,CID)
五、唯一约束
*/
create table SC
(
SID int ,
CID int ,
Score numeric( 4,1 ) check (Score >=0 and Score <= 100 ) , -- 0 , 100 , 99.5
primary key ( SID , CID ),
foreign key (SID) references S(SID),
foreign key (CID) references C(CID)
)
insert into SC values(1001 , 1 , 100)
insert into SC values(1001 , 2 , 90)
insert into SC values(1002 , 2 , 10)
-- DDL(create,drop,alter and so on) 和 DML(update,insert,delete and so on)语句
/*
约束的标准语法
*/
create table S
(
SID int not null, -- PK 主键
SName varchar(10) not null, -- 不能为空约束
SSex char(2) , -- 必须存储 男或者女 检查约束
SBirthday datetime,
SAddress nvarchar(100),
SStatus bit
)
GO
alter table S add constraint PK_S_001 primary key(SID)
alter table S add constraint CHK_S_001 check( SSex in ('男' , '女') )
create table C
(
CID int identity(1,1) not null,
CName varchar(100)
)
alter table C add constraint PK_C_001 primary key(CID)
alter table C add constraint UNQ_C_001 unique(CName)
create table SC
(
SID int not null,
CID int not null,
Score numeric( 4,1 )
)
alter table SC add constraint PK_SC_001 primary key( SID , CID )
alter table SC add constraint FK_SC_001 foreign key ( SID ) references S(SID)
alter table SC add constraint FK_SC_002 foreign key ( CID ) references C(CID)
alter table SC add constraint CHK_SC_001 check ( Score between 0 and 100 )
/*
第六种,意外(缺省约束)
*/
create table test
(
id int identity(1,1) primary key,
status char(1) default('1'),
memo varchar(100)
)
insert into test(memo) values('杨广!!!')
insert into test(status , memo) values( NULL ,'鲁班!!!')
select * from test;
/*
课下作业二:旅游局的ER,表已经出来了,(约束,设计他的域)
用脚本实现
*/
/*
uniqueidentifier ==> newid()
*/
create table test2
(
id int identity(1,1) primary key,
number int not null,
[type] char(2)
)
GO
select * from test2;
insert into test2 values(
1
, '红' )
insert into test2 values(
2
, '红' )
insert into test2 values(
3
, '红' )
insert into test2 values(
4
, '红' )
insert into test2 values(
5
, '红' )
insert into test2 values(
6
, '红' )
insert into test2 values(
7
, '红' )
insert into test2 values(
8
, '红' )
insert into test2 values(
9
, '红' )
insert into test2 values(
10
, '红' )
insert into test2 values(
11
, '红' )
insert into test2 values(
12
, '红' )
insert into test2 values(
13
, '红' )
insert into test2 values(
14
, '红' )
insert into test2 values(
15
, '红' )
insert into test2 values(
16
, '红' )
insert into test2 values(
17
, '红' )
insert into test2 values(
18
, '红' )
insert into test2 values(
19
, '红' )
insert into test2 values(
20
, '红' )
insert into test2 values(
21
, '红' )
insert into test2 values(
22
, '红' )
insert into test2 values(
23
, '红' )
insert into test2 values(
24
, '红' )
insert into test2 values(
25
, '红' )
insert into test2 values(
26
, '红' )
insert into test2 values(
27
, '红' )
insert into test2 values(
28
, '红' )
insert into test2 values(
29
, '红' )
insert into test2 values(
30
, '红' )
insert into test2 values(
31
, '红' )
insert into test2 values(
32
, '红' )
insert into test2 values(
33
, '红' )
insert into test2 values(
34
, '红' )
insert into test2 values(
35
, '红' )
insert into test2 values(
36
, '红' )
insert into test2 values(
1
, '蓝' )
insert into test2 values(
2
, '蓝' )
insert into test2 values(
3
, '蓝' )
insert into test2 values(
4
, '蓝' )
insert into test2 values(
5
, '蓝' )
insert into test2 values(
6
, '蓝' )
insert into test2 values(
7
, '蓝' )
insert into test2 values(
8
, '蓝' )
insert into test2 values(
9
, '蓝' )
insert into test2 values(
10
, '蓝' )
insert into test2 values(
11
, '蓝' )
insert into test2 values(
12
, '蓝' )
insert into test2 values(
13
, '蓝' )
insert into test2 values(
14
, '蓝' )
insert into test2 values(
15
, '蓝' )
insert into test2 values(
16
, '蓝' )
select top 6 * from test2 where type = '红' order by newid()
select top 1 * from test2 where type = '蓝' order by newid()
create table test3
(
id uniqueidentifier primary key,
number int not null,
[type] char(2)
)
GO
insert into test3 values( newid() , 1 , '王' )
select * from test3
/*
新增的几种写法
insert into test3 values( newid() , 1 , '王' ) 我不指定具体的列,必须要求新增的数据的顺序及个数必须是对应的
insert into test(status , memo) values( NULL ,'鲁班!!!') 我指定具体的列,要求你后面新增的值和指定的列的个数及顺序对应
insert into test2 values(
1
, '红' ) 我有自增列,这个时候,不需要指明自僧列
insert into test3 values( newid() , 1 , '王' ) 如果新增的列的数据类型中有uniqueidentifier类型,那么用newid取值
*/
/*删除数据*/
delete from test3
TRUNCATE table test3
/*
相同的地方,都可以删除整个表的数据
区别:truncate不能带条件,delete是一个逻辑删除,truncate是一个物理删除。
delete删除的数据可以通过日志文件找回,但是,truncate删除的数据找不回了。
....... 效率比较低 ........ 效率高
*/
/*
修改 insert into S values( 1002 , '杨玉环' , '女' , '1989-01-01' , '感恩寺' , 1 )
*/
update S set SName = '武则天' , SBirthday = '1841-01-01' where SID = 1002
select * from S
update S set SBirthday = NULL where SID = 1002
--我是62年生人,38+17 = 55岁
/*
利用insert语法进行批量新增
*/
insert into test3
select
newid() , number , type
from test2
insert into test4
select
newid() , number , type
from test2
/*
利用select...into语句,实现对一个新表的批量新增
*/
select * into test4
from test2
select [type]
into test5
from test2
/*
课下作业三:
每个表新增五条数据,新增的有意义
*/
/*
1. 数据类型
int , bit
numeric(p[,s])
datetime datetimeoffset
char varchar , nchar nvarchar , text ntext
uniqueidentifier --> newid
binary varbinary image
2. 创建表的语法 、 删除表的语法
3. 约束
主键约束
不能为空约束
检查约束
唯一约束
外键约束
缺省约束
4. 新增、修改
*/
select * from C
insert into C values( '数学' )
insert into C values( '语文' )
insert into C values( '体育' )
insert into SC values ( 1001 , 1,85 )
insert into SC values ( 1001 , 2,65 )
insert into SC values ( 1001 , 3,100 )
insert into SC values ( 1002 , 1,90 )
insert into SC values ( 1002 , 2,95 )
insert into SC values ( 1002 , 3,75 )
insert into SC values ( 1003 , 1,99 )
insert into SC values ( 1003 , 2,96 )
insert into SC values ( 1003 , 3,40 )
insert into SC values ( 1004 , 1,85 )
insert into SC values ( 1004 , 2,90 )
insert into SC values ( 1004 , 3,85 )
------------------------------------------第三天---------------------------------------------
select * from S
select * from C
select * from SC
--EX01 查询某一个表的所有数据
select * from S
--EX02 查询某一个表的某几列数据(投影) SName , SSex
select SName , SSex from S
--EX03 查询某一个表的某几列数据(投影) 给投影列起别名
select SName as 学生姓名 , SSex as 学生性别 from S
select SName '学生姓名' , SSex '学生性别' from S
select '学生姓名'=SName , '学生性别'=SSex from S
--EX04 查询前2笔数据
select top 2 * from S
--EX05 查询前40%的数据
select top 40 percent * from S
--EX06 查询学生表里面性别有哪一些
select distinct SSex from S
--EX07 聚集函数 count(求元组的个数=求记录的条数) , sum(这一列的总和) , avg , max , min
--1. 求一共有几个学生
select count(*) from S
--2. 求SID为1001的学生的平均分数
select avg(Score) '平均分',sum(Score) '总分',max(Score),min(Score) from SC where SID = 1001
--3. 求CID为1这门课的最高分是多少,最低分是多少 ( 分数(SC-Score),CID(SC) )
select max(Score),min(Score) from SC where CID =1
insert into S values( 1005 , '宋江' , '男' , '1989-01-01' , '梁山' , 1 )
insert into SC values ( 1005 , 1 , NULL )
--4. 求CID为1这门课的平均分数
select avg(Score) from SC where CID = 1
select * from SC where CID = 1
select sum(Score)/5 from SC where CID = 1
--备注:NULL值不计算在内
select count(Score) from SC where CID = 1
--EX08 选择操作 = >= <= != <> > <
--1. 求所有SID编号大于5的学生信息
select * from S where SID > 5
--EX09 AND OR
--1. 求所有在CID为1的这门课上 考了 80分以上的同学编号
-- CID =1 Score > 80
select * from SC where CID =1 and Score > 80
--2. 求所有在CID为1的这门课上 考了 不在 60-90 分之间 的同学编号
select * from SC where CID = 1 and (Score < 60 or Score > 90)
--EX10 我想找到出生日期不详的人
select * from S where SBirthday IS NULL
--EX11 我想找到出生日期详的人
select * from S where SBirthday IS NOT NULL
--EX12 我想找出所有CID=1上考了60-90 分之间 的同学编号
select * from SC where CID = 1 and Score between 60 and 90
--2. 求所有在CID为1的这门课上 考了 不在 60-90 分之间 的同学编号
select * from SC where CID = 1 and (Score < 60 or Score > 90)
--等效于
select * from SC where CID = 1 and Score not between 60 and 90
--EX13 IN 关键字
--找出 杨玉环 , 杨广, 张三丰 这几个同学的信息
select * from S where SName in ( '杨玉环' , '杨广' , '张三丰' )
--找出除了 杨玉环 , 杨广, 张三丰 这几个同学之外的信息
select * from S where SName not in ( '杨玉环' , '杨广' , '张三丰' )
--EX14 模糊查询
--找出所有姓杨的同学信息 % 任意个任意字符
select * from S where SName like '杨%'
--找出所有姓杨的并且名字是三个字的同学信息 _ 一个任意字符
select * from S where SName like '杨__'
--EX15 排序
-- 按照学生的性别,出生日期进行升序排序显示
select * from S order by SSex asc , SBirthday asc
-- 按照学生的性别,出生日期进行降序排序显示
select * from S order by SSex desc , SBirthday desc
--EX16 分组 group by
-- 1. 统计一下学校里面男女生的人数
/*
男 10
女 67
*/
select SSex,count(*) '人数' from S
group by SSex
-- 2. 统计每个学生的平均成绩
/*
SID 平均成绩
1001 89
1002 30
*/
select SID , avg(Score) from SC
group by SID
-- EX17 我想求出所有平均分数高于80分的同学编号和分数,让他们参加竞赛去。
/*
SID 平均成绩
1001 89
分组前过滤用where,分组后过滤用having
*/
select SID , avg(Score) from SC
group by SID
having avg(Score) > 80
-- EX18 IN (查询语句) --- 子查询
-- 查询所有修了 语文的学生的编号
-- 语文(C)
-- SID ( SC )
select * from SC where CID = 2 --语文这门课的编号
select CID from C where CName = '语文'
select * from SC where CID IN (
select CID from C where CName = '语文'
)
--或者
select * from SC where CID = (
select CID from C where CName = '语文'
)
--1. 求所有修了语文的学生信息
-- 语文 (C) 学生信息(S) SC
select * from S where SID in (1001 , 1002 , 1003 , 1004) --( 学生编号1 , 学生编号2 ... )
select SID from SC where CID = 2 -- 语文的编号 1001 1002 1003 1004
select CID from C where CName = '语文'
select * from S where SID in (
select SID from SC where CID = (
select CID from C where CName = '语文'
)
)
-- EX19 并集 union all (不去除重复的) 不带all(去除重复的)
select * into S_History from S
select * from S
union all
select * from S_History where SSex = '男'
select * from S
union
select * from S_History where SSex = '男'
--EX20 intersect 交集
select * from S
intersect
select * from S_History where SSex = '男'
--EX21 EXCEPT A - A^B 补操作
select * from S
EXCEPT
select * from S_History where SSex = '男'
--EX22 乘操作
select * from S , S_History
--EX23 求即修了1这门课,又修了2这门课的学生编号 SC
select SID from SC where CID = 1
intersect
select SID from SC where CID = 2
--EX24 求即修了1这门课,又修了2这门课的学生信息
select * from S where SID in (
select SID from SC where CID = 1
intersect
select SID from SC where CID = 2
)
--课下作业:
--EX25 求即修了语文这门课,又修了数学这门课的学生信息
select CID from C where CName = '语文'
select CID from C where CName = '数学'
select * from S where SID in (
select SID from SC where CID = (select CID from C where CName = '语文')
intersect
select SID from SC where CID = (select CID from C where CName = '数学')
)
--EX26 修了所有课程的学生信息
-- 我们求学生的修的课数 这个课数 = 我们C表的数量
-- 我们要求出每个学生修的课的数量
select * from S where SID in (
select
SID
from SC
group by SID
having
count(*) = (select count(*) from C)
)
--EX27 求2这门课的最高分
-- 求2这门课的分数
select max(score) from SC where CID = 2
--EX28 求语文这门课的最高分
select max(score) from SC where CID = (
select CID from C where CName = '语文'
)
--EX29 求语文这门课的最高分的学生信息
-- 我们要看一看哪一些学生ID 语文 考了96分
-- 我们要看一看哪一些学生 他在CID为2的这门课上 考了96分
select * from S where SID in (
select
SID
from SC where CID = (
select CID from C where CName = '语文'
) and Score = (
select max(score) from SC where CID = (
select CID from C where CName = '语文'
)
)
)
-----------------------第四天----------------------------------
--多表查询
--(1) 等值链接 , 乘操作
select * from S,SC where S.SID = SC.SID
-- 我想求出 (学生编号,学生姓名,课程编号,课程名称,分数)
select S.SID , S.SName , SC.CID , C.CName , Score from S , SC , C
where S.SID = SC.SID and SC.CID = C.CID
--求出每个学生的平均成绩
-- (学生编号,学生姓名,平均成绩)
select
S.SID , SName , avg(SC.Score)
from
S , SC where S.SID = SC.SID
group by S.SID , SName
insert into S values( 1006 , '李白' , '男' , '1989-01-01' , '韩国' , 1 )
select * from S
--求出每个学生的课的数量
-- (学生编号,学生姓名,选修课数)
select
S.SID , SName , count(*)
from
S , SC where S.SID = SC.SID
group by S.SID , SName
-- 思考?
--(2) 内链接 (内链接和等值链接在效果上是一致) 和外链接
select
S.SID , SName , count(*)
from
S inner join SC on S.SID = SC.SID
group by S.SID , SName
--(3) 我想求出 学生的编号,姓名,课程ID , 课程名称,分数
select
S.SID , SName , SC.CID , CName , Score
from S inner join SC on S.SID = SC.SID
inner join C on SC.CID = C.CID
--(4) 左外链接
select
S.SID , SName , SC.CID , SC.Score
from
S left outer join SC on S.SID = SC.SID
select
S.SID , SName , count(SC.CID) '修的课数'
from
S left outer join SC on S.SID = SC.SID
group by S.SID , SName
select
S.SID , SName , SC.CID , CName , Score
from S left outer join SC on S.SID = SC.SID
left outer join C on SC.CID = C.CID
-- (5) 右外联 right outer join
select
S.SID , SName , SC.CID , SC.Score
from
SC right outer join S on S.SID = SC.SID
-- SOME=ANY , ALL
select * from SC where Score >ALL (
select Score from SC where CID = 2 --求2这门课所有的分数
-- 65 , 95 , 96 , 90
)
select * from SC where Score
select Score from SC where CID = 2 --求2这门课所有的分数
-- 65 , 95 , 96 , 90
)
--(6) 排名函数
select
RANK( ) OVER ( order by Score Desc ) '名次' , *
from SC where CID = 1
select
DENSE_RANK ( ) OVER ( order by Score Desc ) '名次' , *
from SC where CID = 1
-- (7) 子查询 求全班数学前三名的同学
select * from (
select
DENSE_RANK ( ) OVER ( order by Score Desc ) '名次' , *
from SC where CID = (
select CID from C where CName = '数学'
)
) A where A.名次 <= 3
-- (8) 学生表的信息,修课的数量
select
S.SID , S.SName , 修课的数量 = (
select count(*) from SC where S.SID = SC.SID )
from
S
-- 课堂作业一:
-- 1. 求哪一些学生没有修课
select * from S where SID not in(
select SID from SC
)
select
S.*
from
S left outer join SC on S.SID = SC.SID
where SC.CID is null
--SP.
select * from S where SID in(
select SID from SC
)
select
distinct S.*
from
S inner join SC on S.SID = SC.SID
-- exists 存在
select
*
from
S where exists ( select * from C where 2 = 1 )
-- 我想查询出所有修了课的学生
select
*
from
S where exists ( select * from SC where S.SID = SC.SID )
-- 2. 求哪一个学生分数没有低于80分的
-- 学生的分数都高于80
select * from S where SID not in (
select SID from SC where Score < 80
) and exists ( select * from SC where S.SID = SC.SID )
----------------------T - SQL-----------------------
/*
1. 申明变量
2. 给变量赋值
3. 读变量的值
*/
declare @name varchar(30)
set @name = '张三丰'
select @name = '战死翁'
print @name
--1. 求SID=1002的学生的平均成绩,并打印出来。
declare @avg_score int
declare @sum_score int
select @avg_score = avg(score) ,@sum_score = sum(score) from sc
where sid = 1002
print @avg_score
print @sum_score
--2. 分支 求SID=1002的学生的平均成绩,如果是90分以上,则输出优秀
-- 如果是80分以上,输出良好,70分以上,输出一般,60分以上,输出及格
-- 60分以下,不及格
declare @avg_score int
select @avg_score = avg(score) from SC where SID = 1002
if @avg_score >= 90
print '优秀'
else if @avg_score >=80
print '良好'
else if @avg_score >= 70
print '一般'
else if @avg_score >= 60
print '及格'
else
print '不及格'
select
SID , SName ,
CASE SStatus
WHEN 1 THEN '在学'
WHEN 0 THEN '离校'
END '状态'
from S -- 1的时候显示在学,如果显示0的时候,离校
declare @avg_score int
declare @status char(6)
select @avg_score = avg(score) from SC where SID = 1002
-- CASE WHEN
SET @status = CASE
WHEN @avg_score >= 90 THEN '优秀'
WHEN @avg_score >= 80 THEN '良好'
ELSE '其他'
END
print @status
--课下作业:----
--1. 用T-SQL 实现下面的功能
-- 查询学号为1003的学生,如果出生日期是NULL,则更新该生的生日为
-- 2005-01-02 ; 如果不为NULL,则更新生日为 2000-01-02
declare @birthday datetime
select @birthday = SBirthday from S where SID = 1003
if @birthday is null
begin
update S set SBirthday = '2005-01-02' where SID = 1003
end
else
begin
update S set SBirthday = '2000-01-02' where SID = 1003
end
select * from S
--2. 新建一个表 结构如下( 教师编号 , 教师姓名, 课程编号 )
-- 1个老师只能教1门课,但是1门课可以被1个老师讲授
-- 课程编号是外键(C(CID))
create table T
(
TID int identity(1,1) primary key,
TName varchar(30) not null,
CID int,
foreign key(CID) references C(CID)
)
--3. LEFT( 字段 , 1 )
-- 求这个学校 姓氏人数的 分布
-- 杨 2
-- 张 3
select left(SName , 1) , count(*) from S
group by left(SName , 1)
--4. 用T-SQL求出 杨玉环是哪一个星座的?
declare @month int
declare @day int
declare @xingzuo varchar(20)
select @month = month( SBirthday ) , @day = day( SBirthday ) from S where SName = '张三丰'
set @xingzuo = case
when (( @month = 4 and @day > 21 ) or ( @month = 5 and @day < 21 ))
then '金牛座'
when (( @month = 5 and @day > 21 ) or ( @month = 6 and @day < 18 ))
then '双子座'
else '不知名星座'
end
print @xingzuo
select * from S where SName = '张三丰'
-----------------------第五天----------------------------------
-- 循环 WIHLE 布尔表达式 begin 一条一条的语句 end
-- 打印五个下午好
declare @count int --计数器
set @count = 0
while ( @count < 5 )
begin
print '下午好'
set @count = @count + 1
end
-- break continue
declare @count int --计数器
set @count = 0
while ( @count < 5 )
begin
if @count = 2
break;
set @count = @count + 1
print '下午好' + cast(@count as varchar(10))
end
declare @count int --计数器
set @count = 0
while ( @count < 5 )
begin
set @count = @count + 1
if @count = 2
begin
continue
end
print '下午好' + cast(@count as varchar(10))
end
-- 函数
select @@Version --全局的,系统级别
select @@error
-- 1. DateAdd 在指定的日期上添加一个指定的时间,比如:
-- 我可以求得当前日期推后三天,是哪一天?
-- 小明是2005-01-01出生,小明的妹妹450天以后出生,
-- 问小明的妹妹是哪一天出生的。
-- 小明的二表妹是78个星期后出生的,问他二表妹的生日
select dateadd( dd , 450 ,'2005-01-01')
select dateadd( ww , 78 ,'2005-01-01')
-- DateDiff 求两个时间差
-- 小明是2005-01-01出生,小明的妹妹是2007-05-21出生的,
-- 问小明和小明的妹妹差多少个周
select datediff( hh ,'2005-01-01', '2007-05-21' )
-- 统计S表中,每个月份过生日的人数
select
datepart( mm ,SBirthday) , count(*)
from
S
group by
datepart( mm ,SBirthday)
select day( getdate() )
select month( getdate() )
select year( getdate() )
-- 四舍五入
select round( 89.56 , 1 )
--LEFT 求所有姓杨的人数
select count(*) from S where LEFT( SName , 1 ) = '杨'
-- RIGHT
select count(*) from S where RIGHT( SName , 1 ) = '丰'
-- LTRIM , RTRIM
select RTRIM(LTRIM(' A ')), ' A'
--SUBSTRING
select SUBSTRING( '你是大坏蛋' , 1 , 1 )
--REPLACE
select REPLACE( '你是大坏蛋' , '你' , '它' )
-- 课下作业一:小明的爸爸要在2005-2-23退休了,拉着小明的手,对小明说,
-- 你要继承我的事业,我是一个打鱼,打鱼要三天打鱼,两天晒网。
-- 问小明在今天是打鱼还是晒网
-- 课下作业二:求n的斐波拉切数列
-- 课下作业三:求1000以内的素数
-- 游标 (遍历结果集的游标-->显示游标)
DECLARE @SID INT
DECLARE @SName varchar(30)
DECLARE MyCursor CURSOR FOR
SELECT SID ,SName FROM S
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @SID,@SName
PRINT CAST(@SID AS VARCHAR(20)) + @SName
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM MyCursor INTO @SID,@SName
PRINT CAST(@SID AS VARCHAR(20)) + @SName
END
CLOSE MyCursor
DEALLOCATE MyCursor
-- 课下作业四,遍历学生分数,如果这个学生分数小于60分,我就给这个学生提高5分。
-- 用游标
-- 视图 View : 里面封装复杂的SQL
create view v_student
as
select
datepart( mm ,SBirthday) '月' , count(*) '人数'
from
S
group by
datepart( mm ,SBirthday)
create view v_student1
as
select
S.SID , SName , SC.CID , CName , Score
from S left outer join SC on S.SID = SC.SID
left outer join C on SC.CID = C.CID
create view v_student2
as
select * from v_student
--使用视图就和使用表一样
select * from v_student2
alter view v_update_student
as
select top 1 * from S
update v_update_student set SName = '张思丰' where SName = '张三丰'
select * from v_update_student
update v_student set SName = '张三丰' where SName = '张思丰'
-- 视图的特征:
/*
视图是一个虚拟表,其内容由查询SQL语句定义。
同真实的表一样,视图包含一系列带有名称的列和行数据。
行和列数据来自于定义视图的查询所引用的表,并且在引用视图时动态生成。
对其中所引用的基础表来说,视图的作用类似于筛选。
定义视图的筛选可以来自当前或其他数据库的一个或多个表,或者其他视图。
通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也不少。
*/
drop view v_student
select * from v_student
--索引:为了检索的速度
create INDEX IDX_Student ON S(SSex);
create unique INDEX IDX_Student_sex ON S(SSex);
select * from S where SSex = '男'
drop index S.IDX_Student --删除索引
-- 备注:什么时候用索引
-- 当一个列的数据值重复的比较多的时候
-- 一般情况下 占10%以内
-- 主键会默认给他创建主键索引( 唯一的索引,而且不能为空 )
--预习:存储过程,函数,触发器
create function my_fun ( @STR1 varchar(30) , @STR2 varchar(30) )
returns varchar(60)
as
begin
return @STR1 + @STR2
end
select dbo.my_fun( '张三丰' , '大好人' )
select dbo.my_fun( SName , SSex ) from S
drop function my_fun
select getdate()