黑马程序员-自学笔记-SQL Server与ADO.Net(三)

SQL Server与ADO.Net(三)

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

1、Top

l  获取前几条数据,放在列前面,与order by一起使用

l  排序

•    -> select * from 表名 order by 字段 asc

•    -> asc表示升序、desc表示降序

l  查询(百分比向右对齐)

•    -> select top 3 * from 表名 order by Age asc

•    -> select top 5 percent * from 表名

 

2、Distinct

l  distinct去除重复的数据(distinct是对整个结果集进行数据重复处理,不是针对某一列)

l  检查返回不重复的数据(对于整条记录不重复才会去除)

•    select distinct * from 表名

l  针对某一列去除重复,检索数据

•    select distinct(需要去除的字段),其他字段 from 表名

 

3、聚合函数

l  MAX(字段)

l  MIN(字段)

l  AVG(字段)

•    在计算时,对于null的数据不计入总是

l  SUM(字段)

l  COUNT(字段)

•    count(*)计算所有的列、count(字段)不计为null的列

l  -> select的字段可以当做变量名来进行计算

•    select (english+math)/2 as 平均分 form score

l  计算时null表示未知,既不是最大,也不是最小,与null的运算结果也为null

 

4、带条件的查询

l  select …from…where

•    查询没有及格的学生的学号

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

l  between…and …在之间,包含两端

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

•    查询math成绩在80-90分之间的所有学生

l  查询班级id为1,2,3的所有学生:in(val1,val2,val3)

•    select sName,sAge from studentwhere sClassId=1 or sClassId=2 or sClassId=3

•    select sName,sAge from studentwhere sClassId in (1,2,3)

 

5、带条件的查询-模糊查询

l  查询所有姓张的同学

•    select * from student whereleft(sName,1)=‘张‘   看上去很美,如果改成查询名字中带亮的学生怎么做?

l  换一种做法 like 

•    select  * from student where sName like ‘张%’    会吧所有姓张的都查询到,现在我想查询姓张并且名字是一个字的学生?

•    select  * from student where sName like ‘%亮%’

l  通配符 %多字符匹配的通配符,它匹配任意次数(零或多个)出现的任意字符

l  通配符_ 单字符匹配,它匹配单个出现的字符

l   [] 只匹配一个字符 并且这个字符必须是[]范围内的,或[_]

l  not与like一起使用:not like ….

 

6、空值处理

l  查询所有生日为null的姓名

•    -> select Fname from T_StudentFbirthday is null

l  判断null只能使用is或is not

•    is null和is not null

l  函数 isnull(字段名, 替换值)

•    查询时专门为空值的字段显示处理

•    select isnull(字段,123) from 表名

l  空字符串与null含义不同,空字符串依旧有内容

•    处理空字符可以使用len()函数和is null

 

7、数据排序

l  排序order by

l  如果有where筛选,order总放在后面

•    select * from … where … order by …

l  多列排序(从左至右)

•    select * from 表名 order by

•    字段1 [desc], 字段2 [desc], 字段3[desc]

l  datalength()系统函数,计算字节数

l  len()函数,计算字符数

l  注:ORDER BY子句位于SELECT语句的末尾,它允许指定按照一个列或者多个列进行排序,还可以指定排序方式是升序(从小到大排列,ASC)还是降序(从大到小排列,DESC)。

 

8、数据分组

l  select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息

l  按性别分组

•    select FSex form T_Student groupby Fsex

l  按班级分组,计算总人数

•    select FClass, count(*) as 班级总人数 from T_Student group byFClass

l  筛选班级人数大于3的

•    where能使用吗?where是分组前对数据进行筛选

•    筛选人数,是将班级分完组后再统计的,这里使用having

•    having表示分组后对数据的筛选

•    select FClass, count(*) as 班级人数 from T_Student group byFClass having count(*)>3

l  在查询语句中使用了group by子句后,只能select聚合函数与分组的字段

l  查询列中使用聚合函数后,不允许出现除分组列外的其他列

l  注:可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息. 按照group by 子句中指定的表达式的值分组查询结果。

 

9、having语句

l  having 是group by的条件对分组后的数据进行筛选(与where类似,都是筛选,只不过having是用来筛选分组后的组的。)

l  在where中不能使用聚合函数,必须使用having,having要位于group by之后,

l  查询班级人数超过三个人的班级

•    select FClassId,count(FName) fromT_Student group by FClassId having count(FName)>3

•    注意having中不能使用未参与分组的列,having不能替代where。作用不一样,having是对组进行过滤

 

10、联合结果集

l  union就是将多个结果集合并成一个结果集

l  查询语句1 union 查询语句2

l  union会自动合并重复的数据

l  union all会保留重复数据

•    一般都是使用union all,效率会高点

l  联合需要注意类型一致

•    cast()函数可以实现数据的类型转换 ,如:cast(字段名或聚合函数 as 类型)

l  一次插入多条数据:

insert into Score(studentId,english,math)

select 1,80,100 union

select 2,60,80 union

select 3,50,59 union

select 4,66,89 union

select 5,59,100

 

11、一次插入多条数据

l  把现有表的数据插入到新表(表不能存在)

l  select * into newStudent fromstudent(newStudent表在select查询的同时自动建立。)

•    --把现有表的数据复制到一个已存在的表

•    通过这种方式复制,只能复制表中的数据,以及列的名字和数据类型,对于约束,不会复制过来。

l  insert into backupStudent select *from students  (backupStudent表必须提前建好)

 

12、字符串函数(掌握)

l  LEN() :计算字符串长度(字符的个数。)

l  datalength();//计算字符串所占用的字节数,不属于字符串函数。

l  LOWER() 、UPPER () :转小写、大写

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

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

l  LTRIM(RTRIM('         bb        '))

l  LEFT()、RIGHT()  截取取字符串

•    SELECT LEFT('abcdefg',2)

l  SUBSTRING(string,start_position,length)

           参数string为主字符串,start_position为子字符串在主字符串中的起始位置,该位子从1开始

           length为子字符串的最大长度。

            SELECT SUBSTRING('abcdef111',2,3)

 

13、日期函数

l  获得系统当前时间:getdate()

•    select getdate()

•    当前是第几天:select day(getdate())

•    当前的年份:select year(getdate())

•    当前的月份:select month(getdate())

l  在当前时间加上一个时间间隔

•    dateadd(在哪个部分增加,增加多少,日期)

l  判断两个日期的间隔

•    datediff(单位,开始的时间,结束的时间)

l  实例:将学生按年龄分组(学生表要有出生年月)

•    selectdatediff(year,sBirthday,getdate()),count(*)

•    from student group bydatediff(year,sBirthday,getdate)

l  返回日期的特定部分

•    datepart()

•    实例:统计学生生日的年份数量(某一年的有多少个等)

•    selectdatepart(year,sBirthday),count(*)

•    from student group bydatepart(year,sBirthday)

 

14、类型转换函数

l  CAST ( expression AS data_type)

l  CONVERT ( data_type,expression,[style])

l  Select ‘您的班级编号’+ 1  错误这里+是数学运算符

•    SELECTFIdNumber,

•    CAST(RIGHT(sNo,3)AS INTEGER) as 后三位的整数形式,

•    CAST(RIGHT(sNo,3)AS INTEGER)+1 as 后三位加1,

•    CONVERT(INTEGER,RIGHT(sNo,3))/2as 后三位除以2

•    FROMstudent

l  对日期的转换。转换成各种国家格式的日期。

•    selectconvert(varchar(20),getdate(),104)

•    Style的格式,查sql帮助。(输入convert函数查询)

•    将日期转换为指定格式的字符串。日期→字符串

 

附:随机练习代码:

/*

    复习

    建数据库 create database 数据库名

    建表    create table 表名(字段类型默认值)

    建约束      至少知道如何通过设计器实现

   

    增删改查

            insert into 表名(字段列表)values(值列表)

            delete from 表名where 条件

            update 表名set 字段=where条件

            select * from 表名

*/

use School

go

select * from MyStudent;

 

--==Top==

select top 10 percent

    --GETDATE() as 当前时间,

    Fid asid,

    FName as姓名,

    FAge 年龄,

    FGender 性别,

    数学成绩=FMath,

    英语成绩=FEnglish,

    (FMath+FEnglish)/2 as 平均成绩,

    FMath+FEnglish as 总成绩

from MyStudent

where FMath+FEnglish>=100

order by FMath desc,FEnglish desc  --desc降序,默认asc升序

 

--==Distinct==

create table 重复数据

(

    id intidentity(1,1) primary key,

    ch_name nvarchar(10)

)

insert into 重复数据 values('张三');

insert into 重复数据 values('张三');

insert into 重复数据 values('张三');

insert into 重复数据 values('张三');

select distinct * from 重复数据;

--对于整条记录不重复才会去除

create table 重复数据

(

    id int,

    ch_name nvarchar(10)

)

insert into 重复数据 values(1,'张三');

insert into 重复数据 values(2,'张三');

insert into 重复数据 values(3,'张三');

insert into 重复数据 values(4,'张三');

select distinct * from 重复数据;

 

--====聚合函数====

select * from MyStudent order by FMath desc;

--max,min,avg,sum,count

select MAX(FMath),MIN(FMath),AVG(FMath),SUM(FMath),COUNT(FMath) from MyStudent;

--用法上需要注意的聚合函数

--avg     不对null数据进行处理,求平均值时null数据不计入总数

--count      当处理所有数据时,即*返回总行数,即使没有数据;当处理某个字段时,只考虑非null的数据

create table TBL

(

    id intidentity(1,1) primary key,

    [name] nvarchar(10),

    score int

)

go

insert into TBL([name],score) values('张三',100);

insert into TBL([name]) values('小张');

insert into TBL([name],score) values('李四',90);

insert into TBL([name]) values('小曼');

insert into TBL([name],score) values('王五',70);

 

select * from TBL;

select SUM(score)/5 as 除以,SUM(score)/3 as 除以,AVG(Score) 平均值 from TBL;

select COUNT(*),COUNT(Score),COUNT(1) from TBL;

 

--====条件查询===

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

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

select * from MyStudent;

select * from MyStudent where FMath<90 and FEnglish<90 or FMath<90 or FEnglish<90 order by FMath,FEnglish;

select * from MyStudent where FGender='' and  FAge>=20 and FAge<=30;

 

--betweenand   (包括边界)

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

--查询math成绩在-90分之间的所有学生

select * from MyStudent where FAge between 20 and 30 and FGender='';

select * from MyStudent where FMath between 80 and 90 order by FMath;

 

--查找id号为,,...的学生

select * from MyStudent where Fid in(1,11,111,2,22,222);

 

--模糊查询

--查找氖姓杜的学生

-- % 0个或多个  _ 一个

select * from MyStudent where FName like '%';

select * from MyStudent where FName like '__';

select * from MyStudent where FName not like '[,][][^]';

select * from MyStudent where FName like '_[^][^]_';

select * from MyStudent where FName like '%%' and FName not like '%%';

 

--==null值处理==

select * from TBL;

--查询某一个字段数据为null的情况

select * from TBL where [name] is not null and score is null;

--null数据默认添加一个指定的数据

select [name],ISNULL(score,0) from TBL;

--空字符串len()求长度

select [name],LEN([name]),Score from TBL where id=4;

 

--==数据排序==

select [name],LEN([name]) as [len],DATALENGTH([name]),Score from TBL;

select * from MyStudent order by FAge desc,LEN(FName);

 

--==数据分组==

select COUNT(*) from MyStudent where FGender='';

--分组

select FGender,COUNT(FGender) from MyStudent group by FGender;

--只要有分组,那么数据查询中的字段必须包含在分组字段中,同时可以包含聚合函数.

 

--男女分组后求平均分和总分

select FGender as 性别,COUNT(FGender) as 总人数, AVG(FMath) as 数学平均分,AVG(FEnglish) 英语平均分 from MyStudent groupby FGender

 

--按照英语成绩进行分组,并统计平均分大于的人数

select

    FEnglish,COUNT(FEnglish) as 人数,AVG(FEnglish)

from MyStudent

group by FEnglish

having AVG(FEnglish)>80

--查询前的筛选

--  where

--查询后的筛选

--  having

 

--======练习===========

use MyBook

go

-- 检索

select * from T_Book where LEN(FProperty)=0;

--加上条件,分组条件

--1、按照属性分组

select FProperty from T_Book group by FProperty;

--分组后的数据,只能检索分组字段和聚合函数

select FProperty,COUNT(FProperty) from T_Book group by FProperty;

 

--2、按出版社分组

select FPublic,COUNT(FPublic) from T_Book group by FPublic;

 

--常常处理检索时的筛选

--1、将教材筛选出来,并执照出版社分组,统计各出版社书的总数

--先筛选、再检索

select FPublic,COUNT(FPublic) as 总数 from T_Book whereFProperty='教材' group by FPublic;

 

--2、在的基础上,统计出版社出版书籍大于本的出版社

--现在是先筛选还是先检索?

--这个是先检索,在结果中筛选

select

    FPublic,

    COUNT(FPublic)    --得到统计数据

from T_Book

where

     FProperty='教材'        --一开始将数据提取出来

group by

    FPublic             --按照出版社分组

having

    COUNT(FPublic)>=3

 

--========联合================

--1将教材大于本的出版社显示出来

--  筛选教材

--  统计总数,判断大于

--  结果是出版社

 

--2、将教辅的出版社输出出来,并显示其中出版数量

--  筛选教辅

--  显示出版社

--  统计数据

 

--3、汇总以上两个数据

--  SQL语句union SQL语句

select FPublic,COUNT(FPublic) from T_Book

where FProperty='教材' group by FPublic    having COUNT(FPublic)>=10

union

select FPublic,COUNT(FPublic) from T_Book

where FProperty='教辅' group by FPublic;

 

--联合多用于财务汇总

--查询学生的数学与英语成绩

use School

go

select Fname,Fmath from MyStudent

union

select '总成绩',SUM(Fmath) from MyStudent

union

select '平均成绩',avg(Fmath) from MyStudent

union

select '最高分',max(Fmath) from MyStudent

union

select '最低分',min(Fmath) from MyStudent;

--联合的时候必须保证列数相同

--联合的时候必须保证同列的类型相兼容

 

--关于联合的重复

select* into TBL1 from TBL;

select * from TBL

union             --联合会将重复数据过掉

select * from TBL1;

--处理union时一般保留重复数据

--会反复检查排除重复

select * from TBL

union all         --联合unionall保留重复数据

select * from TBL1;

 

--==练习==

--1要求一个表格中查询出学生的英语成绩最高分、最低分、平均分

select * from MyStudent;

select '最高分',MAX(FEnglish) from MyStudent

union

select '最低分',min(FEnglish) from MyStudent

union

select '平均分',avg(FEnglish) from MyStudent;

--2查询每位老师的信息,包括姓名、工资,并且在最后一行加上平均工资和最高工资

select tName,tSalary from teacher

union all

select '平均工资',avg(tSalary) from teacher

union all

select '最高工资',avg(tSalary) from teacher

 

--union实现一次加入多条数据

insert into Score(studentId,english,math)

select 1,80,100 union

select 2,60,80 union

select 3,50,59 union

select 4,66,89 union

select 5,59,100;

 

--==字符串函数==

select [name],LEN([name]),DATALENGTH([name]) from TBL;

--函数名(处理对象,相应参数)

select UPPER('abc'),LOWER('ABC')

 

--ltrim()  -- left trim

--rtrim()  -- right trim

select LEN('123456         '),LEN('         123456'),LTRIM('         123456'),DATALENGTH('123456         '),RTRIM('123456

         ');

--去两端

select LTRIM(RTRIM('         bb        '));

 

--替换

select REPLACE('a b c d e f g',' ','_');

 

--截取

select LEFT('abcdef',3); --abc

select RIGHT('abced',3); --ced

select SUBSTRING('abcdefg',1,3);   --abc

--SUBSTRING() 起始位置从开始

 

select UNICODE('abc');

select datalength(NCHAR(97)),DATALENGTH( CHAR(97));

 

---===时间函数==

create table BookOrder

(

    id int,

    [time] datetimedefault(getdate())

)

--1、一种给表一个默认约束

--2insert的时候加上数据时间

select * from BookOrder;

insert into BookOrder(id) values(1);

insert into BookOrder values(2,GETDATE());

insert into BookOrder values(3,'2013-10-1');

 

--查询id=2的时间,并显示出年月日出来

select YEAR([time]),MONTH([time]),DAY([time]) from BookOrder where id=2;

 

--在年份上加一个dateAdd()

select DATEADD(yy,1,[time]) from BookOrder where id=2;

--判断两个日期的间隔

select datediff(yy,[time],[time]) from BookOrder where id=2;

--返回日期的特定部分

select DATEPART(ms,getdate());

 

--========类型转换函数在帮助文件的系统函数中

-- cast(数据as类型)

select CAST(1 as nvarchar(10))+CAST(10 as nvarchar(10));

select CAST('1' as int)+CAST('10' as int);

 

--convert(类型,数据)

select CONVERT(nvarchar(10),GETDATE(),102);

 

select CAST(year(getdate()) as nvarchar(10))+''+CAST(month(getdate()) as nvarchar(10))+''+CAST(day(getdate()) as nvarchar(10))+'';

 

---====练习===

--创建一张表,记录电话呼叫员的工作流水,记录呼叫员编号、对方号码、通话开始时间、通话结束时间。建表、插数据等最后都自己写SQL语句。

--要求:输出所有数据中通话时间最长的条记录。orderby datediff

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

--输出本月通话总时长最多的前三个呼叫员的编号。

 

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

CREATE TABLE [CallRecords]

(

    [Id] [int]NOT NULL identity(1,1),

    [CallerNumber] [nvarchar](50), --三位数字,呼叫中心员工编号(工号)

    [TelNum] [varchar](50),

    [StartDateTime] [datetime] NULL,

    [EndDateTime] [datetime] NULL  --结束时间要大于开始时间,默认当前时间

)

 

--主键约束

alter table [CallRecords]

add constraint PK_CallRecords primarykey(id)

 

--检查约束

alter table [CallRecords]

add constraint CK_CallRecords check(CallerNumber like '[0-9][0-9][0-9]')  

 

alter table [CallRecords]

add constraint CK_CallRecords_EndDateTime check(EndDateTime > StartDateTime)

 

--默认约束

alter table [CallRecords]

add constraint DF_CallRecords default(getdate()) for EndDateTime

 

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('001', '0208888888', CAST(0x00009DAF00A4CB80AS DateTime), CAST(0x00009DAF00A62E94 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('001', '0208888888', CAST(0x00009DB000D63BC0AS DateTime), CAST(0x00009DB000D68DC8 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('001', '89898989', CAST(0x00009DB000E85C60AS DateTime), CAST(0x00009DB000E92F50 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('002', '98987676', CAST(0x00009DB2015BB7A0AS DateTime), CAST(0x00009DB2015C4DA0 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('002', '02188839389', CAST(0x00009DA4014C9C70AS DateTime), CAST(0x00009DA4014E0308 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('001', '767676766', CAST(0x00009DB400DAA0C0AS DateTime), CAST(0x00009DB400DD5FE0 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('003', '0227864656', CAST(0x00009DB200B9AB40AS DateTime), CAST(0x00009DB200B9FC1C ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('003', '676765777', CAST(0x00009DB8014042B8AS DateTime), CAST(0x00009DB80141804C ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('001', '89977653', CAST(0x00009D9A00FB9898AS DateTime), CAST(0x00009D9A00FE6118 ASDateTime));

INSERT [dbo].[CallRecords]([CallerNumber], [TelNum], [StartDateTime], [EndDateTime]) VALUES ('004', '400400400', CAST(0x00009D9A00FB9898AS DateTime), CAST(0x00009D9A00FE6118 ASDateTime));

 

 

 

--查询通话时间最长的条记录

select datediff(second,StartDateTime,EndDateTime) from CallRecords

 

select top 5 datediff(second,StartDateTime,EndDateTime),Id, CallerNumber, TelNum, StartDateTime, EndDateTime

from CallRecords order by datediff(second,StartDateTime,EndDateTime) desc

 

--查询长途的通话总时长

select sum(datediff(second,StartDateTime,EndDateTime)) from CallRecords

where TelNum like '0%'

 

--查询本月通话总时长最多的前三个呼叫员的编号

select top 3 [CallerNumber],sum(datediff(ss,[StartDateTime],[EndDateTime])) from CallRecords

--whereyear(StartDateTime) = year(getdate()) and month(StartDateTime)=month(getdate()) 

where datediff(month,[StartDateTime],'2010-07-1') = 0

group by [CallerNumber]

order by sum(datediff(ss, [StartDateTime],[EndDateTime])) desc

 

--查询本月拨打电话次数最多的前三个呼叫员的编号

select top 3 [CallerNumber],count(*)  from CallRecords

where datediff(month,[StartDateTae],'2010-07-1') = 0

group by [CallerNumber]

order by count(*) desc

 ---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值