黑马程序员-数据库2

本文深入探讨了SQL查询中的关键技巧,包括数据分组、限制结果集行数、联合结果集等操作,同时介绍了如何利用索引提升查询效率,以及各种SQL函数的应用场景。

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

数据分组

按照年龄进行分组统计各个年龄段的人数:SELECT FAge,Count(*) FROM T_Employee GROUP BY FAge,根据年龄进行分组然后取出每组的人数。

GROUP BY子句必须方法WHERE语句之后

没有出现在GROUP BY子句中的列是不能放到SELECT语句后的列名列表中的(聚合函数中除外)

  错误:SELECT FAge,FSalary FROM T_Employee GROUP BY FAge

  正确:SELECT FAge,AVG(FSalary) FROM T_Employee GROUP BY FAge

Having语句

/聚合函数不能出现在WHERE子句中,不许使用HavingHaving要位于Group By之后,SELECT FAge,Count(*) FROM T_Employee GROUP BY FAge Having Count(*)>1

错误:SELECT FAge,Count(*) FROM T_Employee GROUP BY FAge having FSalary>2000,错的,having中不能使用未参加分组的列,having是对分组后信息的过滤,能用到列和select中能用到列一样,having无法代替where

限制结果集行数

Select top5*from T_Employee order by FSalary Desc

(*)检索按照工资从高到低排序检索从第六名开始一共三个人的信息:SELECT top 3* FROM T_Employee WHERE FNumber NOT IN(SELECT TOP 5 FNumber FROM T_Employee ORDER BY FSalary DESC)ORDER BY FSalary DESC.

SQL SERVER2005后增加了Row_Number函数简化实现,可以分页

去掉重复数据

SELECT FDepartment FROM T_Employee->SELECT distinct FDepartment FROM T_Employee

DISTINCT是对整个结果集进行数据重复处理的,而不是针对每一个列(字段)。因此下面的语句并不只会保留Fdepartment进行重复值处理:

SELECT DISTINCT FDepartment,FSubCompany FROM T_Employee

联合结果集

简单的结果集联合:

SELECT FNumber,FName,FAge FROM T_Employee UNION SELECT FIdCardNumber,FName,FAge FROM T_TempEmployee

UNION合并两个查询结果集,并且将其中完全重复的数据行合并为一行。

基本原则:每个结果集必须有相同的列数;没个结果集的列必须类型相同

例子:SELECT FNumberFNameFAge,FDepartment FROM T_Employee UNION SELECT FIdCardNumber,FName,FAge,'临时工,无部门' FROM T_TempEmployee

注意:如果联合数据里有两个相同点数据可能会丢失数据,如果不想合并行就加UNION ALL

UNION因为要进行重复值扫描,所以效率低,因此如果不是确定要合并重复行,那么就要用UNION ALL

例子:

1SELECT '正式员工最高年龄',MAX(FAge)FROM T_Employee

将显示 正式员工最高年龄 年龄

2、查询每位员工信息,包括工号、工资,并在最后加上工资合计:

SELECT FNumberFSalary FROM T_Employee

UNION

SELECT '工资合计'SUM(FSalary) FROM T_Employee

数据库函数:

1、数字函数(*

ABS():求绝对值

CEILING():舍入到最大整数。3.33将被舍入为42.89将被舍入为3.ceiling->天花板.

FLOOR():舍入到最小整数。3.33将被舍入为3,2.892-3.12-4floor->地板

ROUND():四舍五入。涉入到离我半径最近的数。Round->半径,ROUND(3.1425,0)后面的参数为0,表示精确度为0

2、字符串函数(*

LEN():计算字符串长度

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

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

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

SUBSTRING(string,start_position,length)参数string为主字符串,start_positon为子字符串在住字符串中的起始位置,length为子字符串的最大长度。

SELECT SUBSTRING('abcdef111',2,3)

3、日期函数

GETDATE():取当前日期

DATEADD(datepart,number,date),计算增加以后的日期。参数date为带计算的日期;参数number为增量;参数datepart为计量单位。DATEADD(DAY,3,date)为计算日期date3天后的日期,而DATEADD(MONTH,-8,date)为计算日期date的八个月之前的日期。

Datepart可选值

取值   别名   说明

year   yy,yyyy  年份

quarter   qq,q   季度

month   mm,m   月份

dayofyear  dy ,y  当年度的第几天

day       dd,d   

week     wk,ww 当年度的第几周   

weekday   dw,w 星期几

hour     hh    小时

minute   mi,n   

second   ss,s   

millisecond  ms    毫秒

DATEDIFF(datepart,startdate,enddate):计算两个日期之间的差额。Datepart为计量单位,可取参考值DateAdd

例子:统计不同工龄的员工个数:select DATEDiff(year,FInDate,getdate()),count(*) from T_Employee group by DateDiff(year,FInDate,getdate())

DATEPART(datepart,date):返回一个日期的特定部分

统计员工的入职年份个数:select DatePart(year,FInDate),count(*)from T_Employee group by DatePart(year,FInDate)

4类型转换:

CAST(expression AS data_type)

CONVERT(data_type,expression)

流控函数

1、空值处理函数:

ISNULL(expression,value):如果expression不为空则返回expression,否则返回valueSELECT ISNULL(FName,'佚名') as 姓名 FROM T_Employee

CASE函数用法

单值判断,相当于switch case

CASE expression

WHEN value1 THEN returnvalue1

WHEN value2 THEN returnvalue2

ELSE default

END

例子:SELECT FName,(CASE FLevel WHEN 1THEN 'VIP客户'

WHEN 2 THEN '高级客户'

WHEN 3 THEN '普通客户'

ELSE '客户类型错误'

ENDas FLevelName FROM T_Customer

索引(INDEX)

全表扫描:对数据进行检索(select)效率最差的是全表扫描,就是一条条的找。。

如果有目录可以提高效,比如查字典。所以在数据库中,为了提高检索的速度,可以对经常进行检索的列添加索引,相当于建目录。

SQL中,修改表,然后找到相应列右击,索引键,一定要选择列,是为哪一个字段建索引。

优点:使用索引能提高查询效率。缺点:索引占据空间,而且添加、更新、删除数据的时候也需要同步更新索引,因此会降低InsertUpdateDelete的速度。只在经常检索(WHERE)的字段上创建索引。

*)即使创建了索引,仍然有可能全表扫描,比如like、函数、类型转换等。

表连接Join

订单表通过CustomerId关联客户表,SELECT o.BillN0,c.Name,c.Age from T_Orders as o join T_Customers as c on o.CustomerId=c.Id

*Inner JoinLeft JoinRight Join

子查询:将一个查询语句作为一个结果供其他SQL语句

1、单值的子查询

例子:SELECT 1 AS f1,2,(SELECT MIN(FYearPublished) FROM BOOK),(SELECT MAX(FYearPublished) FROM T_BOOL)AS f4

只有返回一行且仅返回一行、以来的数据的子查询才能当成单值子查询。下面的是错误的:SELECT 1 AS f1,2,(SELECT FYearPublished FROM T_Book)

2、多行单列的子查询

SELECT * FROM  T_Reader WHERE FYearOfJoin IN(2001,2003)

可以这样写:

SELECT *FROM T_Reader WHERE FYearOfJoin IN(SELECT FYear Published FROM T_Bool)

3、限制结果集,返回第3行到第5行的数据:

Select * from

(

SELECT *FROM (SELECT ROW_NUMBER() OVER(ORDER BY FSalary DESC)AS rownum),FNumber,FName,FSalary,FAge FROM T_Employee

) as e1 WHERE e1.rownum>=3 and e1.rownum<=5

ROW_NUMBER()为开窗函数,只能出现在SELECT或者ORDER BY子句中。

----------------------  Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------
详细请查看: http://net.itheima.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值