第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数

时间:2021-06-24 15:47:37

17-数据库开发及ado.net

聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all;  Select into 新表;字符串函数;日期函数

SQL聚合函数

MAX(最大值)、MIN(最小值)、AVG(平均值)、SUM(和)、COUNT(数量:记录的条数)

聚合函数对null不计算。如果一行数据都是null,count(*)包含对空值行、重复行的统计。

--聚合函数演示

select * from TblStudent

--cast convert ???

--平均年龄

select AVG(tsage*1.0) as 平均值 from TblStudent

select AVG(tsage*1.0) 平均值 from TblStudent

select 平均值=AVG(tsage*1.0)  from TblStudent

--报错.当使用聚合函数的时候,注意在select查询列表中不要出现除了使用聚合函数以外的其他列,

--除非该列也使用了聚合函数或者该列包含在了Group By子句中。

select 平均值=AVG(tsage*1.0),tSName from TblStudent

--求和

select SUM(tsage) from TblStudent

--求最大值

select MAX(tsage) from TblStudent

--最小值

select min(tsage) from TblStudent

--总条数

select count(*) from TblStudent

--将tSId=32和tSId=30 tsage=null

update TblStudent set tSAge=null where tSId=32 or tSId=30

--

select COUNT(tsage) as 记录条数 from TblStudent

select

COUNT(tsage),

SUM (tsage),

MAX (tsage),

MIN (tsage),

AVG(tsage)

from tblstudent

select * from TblStudent--主键表

select * from TblScore--外键表

--查询英语没有及格的学生的学号

select tsid from TblScore where tEnglish <60

--查询年龄在-30岁之间的男学生

select * from TblStudent  where tsage<=30 and tsage>=20 and tSGender ='男'

--not and or 是个逻辑运算符,优先级not→and→or

--Between...and...在之间

--查询年龄在-30岁之间的男学生

select * from TblStudent where tSAge between 20 and 30

--查询Math成绩在-70分之间的所有学生

select tsid from TblScore where tmath between 65 and 70

--查询班级ID为,2,3的所有学生

select * from TblStudent where tSClassId in (1,2,3)

select * from TblStudent where tSClassId =1 or tSClassId =2 or tSClassId =3

--如果上面的写法可以优化为下面的这种写法,则尽量用下面这种写法.

select * from TblStudent where tSClassId >=1 and tSClassId <=3

模糊查询(都是针对字符串操作的)

--模糊查询,通配符

select * from TblStudent

--之前的查询使用:=

select * from TblStudent where tSName =N'张犇'

--第一个通配符% 表示任意多个任意字符。

--当使用通配符来匹配的时候必须使用Like

select * from TblStudent where tSName like N'张%'

--通过[]将%包含起来,则%不在是表示一个通配符,而是表示一个普通的字符

select * from TblStudent where tSName like N'%[%]%'

--通配符:_ 表示(单个)一个任意字符。

select * from TblStudent  where tSName like N'貂_'

select * from TblStudent where tSName like N'貂%' and LEN(tSName)=2

--通配符:[]

select * from TblStudent  where tSName like N'张_妹'

select * from TblStudent  where tSName like N'张[0-9]妹'

select * from TblStudent  where tSName like N'张[a-z]妹'

--like 和 not like  [^] 通配符的使用注意区分

select * from TblStudent where tSName like N'张_妹'

select * from TblStudent where tSName not like N'张_妹'

select * from TblStudent where tSName not like N'张[^0-9]妹'

空值处理

--空值处理

--null

select * from TblStudent

update TblStudent set tSName =null where tSId=1 --表示数据库的空值

update TblStudent set tSName ='' where tSId=2 --表示一个长度为零的字符串

--请查询出所有tsage为null的学生记录(以下两种都是错误的。)

select * from TblStudent where tSAge =null

select * from TblStudent where tSAge <>null

--数据库中的null值比较特殊,表示一个unknow的值。不知道的值。

--在数据库中对NULL值不能用=或<>来判断,要判断null值,只能使用一个特殊的运算符IS来判断。

select * from TblStudent where tSAge is  null

select * from TblStudent where tSAge is not null

--isnull(),表示一个函数区别以上的is null

--null与任何运算结果都是NULL

数据排序(order  by)

ASC:升序(从小到大排序)

DESC:降序(从大到小排序)

use Itcast2013

select * from tblscore order by tenglish desc,tMath asc

select *, (tEnglish +tMath )as 总分 from TblScore order by (tEnglish +tMath )desc

--order by 在sql语句中位置一定在最后

--select...3> 对筛选出的数据再进行列的筛选

--from ...1>从数据源中获取数据

--where ...2>从获取的数据中筛选一部分符合要求的数据,where是进行行的筛选

数据分组(group  by) 为了数据统计

Group by子句必须放在where语句之后,Group By与 Order By 都是对筛选后的数据进行处理,而where是用来筛选数据。

use Itcast2013

select * from tblscore order by tenglish desc,tMath asc

select *, (tEnglish +tMath )as 总分 from TblScore order by (tEnglish +tMath )desc

--order by 在sql语句中位置一定在最后

--select...3> 对筛选出的数据再进行列的筛选

--from ...1>从数据源中获取数据

--where ...2>从获取的数据中筛选一部分符合要求的数据,where是进行行的筛选

--数据分组

--Group by子句必须放在where语句之后,Group By与Order By 都是对筛选后的数据进行处理,而where是用来筛选数据。

--1.请从学生表中查询出每个班的班级Id和班级人数:

--从该学生表中统计出每个班的人数。

--当在查询中使用了group by 分组后,则在select 中出现的列,必须是group by 中包含的列或者该列必须在聚合函数中

select tSClassId as 组编号 ,COUNT(*) 该组中的记录条数 from TblStudent  group by tSClassId

--2.请从学生表中查询出每个班级的班级ID和班级中男同学的人数。

select

tSClassId as 组编号 ,

COUNT(*) 男同学人数   --4.

from TblStudent       --1.

where tSGender =N'男' --2.

group by tSClassId   --3.

--在分组前对数据筛选使用where

--而在分组后,对于哪些组保留,哪些组不保留,对于组的筛选则使用另外一个关键是字:Having

--having 是对组后,进行筛选

select

tSClassId as 班级编号,--4.

COUNT(*) as 人数

from TblStudent      --1.

group by tSClassId   --2.

HAVING COUNT(*) >10  --3.

--HAVING 人数>10

--3.在这里不能使用别名"人数",因为sql语句的执行顺序是先执行group by 与having 然后才执行select

--在执行having的时候select还没执行,所以无法使用select中列的别名

select tSClassId,COUNT(tSName)人数   from TblStudent  group by tSClassId

select tSClassId,COUNT(tSName)人数,tSAge   from TblStudent  group by tSClassId,tSAge

select tsgender,tSAddress  ,count(*)

from tblstudent

group by tsgender,tSAddress

--多列分组,则必须满足多列的条件。

--完整的select语句执行顺序

1.from

2.on

3.join

4.where

5.group by

6.with cube 或with rollup

7.having

8.select

9.distinct

10.order by

11.top

----Group by 练习

select * from MyOrders

--1.热销商品排名表

select  商品名称,sum(销售数量) 销售总数

from MyOrders

group by 商品名称

order by 销售总数 desc

--2.统计销售总价超过元的商品名称和销售总结,并按销售总价格降序排列

select 商品名称, 销售总价=sum(销售数量*销售价格)

from MyOrders

group by 商品名称

having sum(销售数量*销售价格)>3000

order by  销售总价 desc

--3.统计各个客户对"可口可乐"的喜爱程度.

select sum(销售数量) 喜爱程度,购买人

from MyOrders

where 商品名称=N'可口可乐'

group by 购买人

order by 喜爱程度 desc

类型转换函数(CAST CONVERT

----类型转换----

--Cast()

--Convert()

select '考试人数:'+100

select '考试人数:'+CONVERT (varchar(3),100)

select '考试人数:'+cast (100 as varchar(3))

--注意如果number是字符串类型,则一定要转为int类型,否则排序有误。

select * from mytest1001 order by CAST(number as int )desc

select * from mytest1001 order by CONVERT(int,number) asc

select GETDATE()

--convert()比cast()多了一个参数,等,查看帮助,可知。(时间转换只有CONVERT())

select CONVERT (char(10),GETDATE(),102)

联合结果集(union)集合运算符

--联合结果集(union)集合运算符

select '黄林',18,'huangling@163.com'

union all--通过union all 就可以把多个结果集联合在一起,把行联合在一起

select 'Magi',18,'yan@163.com'

----必须需要有相同的列,列的数目及类型需要一样

select '黄林',18,

union all--通过union all 就可以把多个结果集联合在一起,把行联合在一起

select 'Magi',18,'yan@163.com'

--当使用union 或union all的时候必须保证多个结果集中的列的数目一致

--并且对应的列的数据类型得一致,至少得兼容

--使用带from子句的union

select * from TblStudent

select * from TblTeacher

--根据上面得出的不一样的列,我们可以选择类型一样的列,且只能对最终结果进行排序

select tSName,tSGender,tSAge from TblStudent

union all

select tTName ,tTGender ,tTAge  from TblTeacher order by tSAge desc

--union 与union all的区别

--union all在进行联合的时候不会去除重复数据

--而union在联合的时候,自动去除重复数据

select tSName ,tSGender ,tSAge  from TblStudent

union all

select tSName ,tSGender ,tSAge  from TblStudent

---通过union 实现底部汇总

select * from MyOrders

select

商品名称,

销售价格=(SUM(销售数量*销售价格))

from MyOrders

group by 商品名称

union all

select '销售总额',SUM(销售数量*销售价格) from MyOrders

insert  into 用法

--select into 用法

--1.insert into 表(列,列)select 列,列from 表where ...

--上面这种写法表示要向一张已存在的表中插入一些数据,这些数据来源于表中。

--2.insert * into 表 from  表where ...

--上面这种写法表示要将表的数据插入到表中,在运行这条SQL语句后,表才会被创建

--如果在执行该SQL语句前,表已存在,则报错。即:该条语句不能重复执行。

--通过select * into 这种方式创建的表与源表的表结构(包括列的个数与列的数据类型,连同列的自增长特性,也会一起创建)

--但是新创建的表中没有任何约束,包括源表中的主键约束也没有了,如果需要则要手动创建。

--select * into 主要目的是为了复制一部分数据。

--如果只想复制表结构,而不要数据,则

select * into  NewOrders from MyOrders 1<>1

--更好的方法如下:

select top 0 * into NewOrders from MyOrders

--也可以将多个表的集合插入到新的表中

select tsname into NewSchool from TblStudent

union all

select ttname from TblTeacher

字符串函数

----字符串函数---

--显示字符的个数,无论中文英文一个字符就是一个字符。

select LEN('我你tA')--结果为

--表示占有的字节数,这个不是字符串函数

select DATALENGTH('我你tA')--结果为

len():计算字符串长度(字符的个数)

datalength():计算字符串所占用的字节数

lower():转小写

upper():转大写

ltrim():字符串左侧的空格去掉

rtrim():字符串右侧的空格去掉

left():截取字符串

right():截取字符串

substring():截取字符串

日期函数(在帮助中输入日期函数

----日期函数(在帮助中输入“日期函数”)

getdate():取得当前日期时间

--dateadd():在指定的日期上加一定的时间或日期新值

print dateadd(month,2,'1990-10-10')

print dateadd(month,-2,'1990-10-10')

dateadd(detepart,number,date)

--计算添加以后的日期。

--参数date为待计算的日期,参数number为增量,参数datepart为计算单位。

datediff(datepart,startdate,enddate) 计算俩个日期之间的差额。

--datepart为计量单位,可取值参考DateAdd.

datepart(datepart,date)

--返回一个日期的特定部分

--思考:查询出入职一年以上的员工(含一年)

select userName  from Test1002 where dateadd(year,1,joinDate)<=GETDATE()

select userName  from Test1002 where dateadd(day,365,joinDate)<=GETDATE()

--DateDiff函数,获取俩个日期时间的差值,根据单位不同,返回值不同。

select DATEDIFF (YEAR,'1991-10-10',getdate())

select DATEDIFF (day,'1991-10-10',getdate())

select DATEDIFF (HOUR,'1991-10-10',getdate())

--统计不同年份出生的同学的人数

select

datepart(year,tSBirthday),COUNT(*)

from TblStudent group by datepart(year,tSBirthday)

--统计不同年龄的同学的人数

select

datediff(year,tSBirthday,GETDATE()),COUNT(*)

from TblStudent group by datediff(year,tSBirthday,GETDATE())

课后作业

use [Itcast2013]

select * from CallRecords

--输出所有数据中通话时间最长的条记录。

select top 5 * ,'通话时长'=DATEDIFF (SECOND,StartDateTime ,EndDateTime) from CallRecords  order by '通话时长' desc

--输出所有数据中拨打长途号码(对方号码以开头)的总时长、Like、SUM

select

拨打长途电话的总时长=SUM(DATEDIFF (SECOND,StartDateTime ,EndDateTime))

from CallRecords

where TelNum like '0%'

--输出【本月】通话总时长最多的前三个呼叫员的编号:group by count(*)

--假设今天是‘-07-31’

select

top 3

CallerNumber,本月通话总时长=SUM(DATEDIFF (SECOND,StartDateTime ,EndDateTime))

from CallRecords

where  datepart(YEAR,StartDateTime) =YEAR('2010-07-31')

and datepart(MONTH ,StartDateTime) =month('2010-07-31')

--限制本月,本月表示表中记录的年份、月份都与当前日期的年份月份相同。才叫本月

group by CallerNumber

order by 本月通话总时长 desc

--输出本月拨打电话次数最多的前三个呼叫员的编号:group by count(*)

select top 3 CallerNumber ,

次数= COUNT(*)

from CallRecords

where  datepart(YEAR,StartDateTime) =YEAR('2010-07-31')

and datepart(MONTH ,StartDateTime) =month('2010-07-31')

group by CallerNumber

order by 次数 desc

--每个月打电话时间最长的前三个呼叫员(**)

select * from vw where 通话时长 in

(select top 3 通话时长 from vw as vw2 where vw2.月份=vw.月份 order by vw2.通话时长 desc )

order by vw.月份,vw.通话时长 desc