transact---sql高级查询(上)
1:多表的查询和笛卡儿积
2:表格别名的用法
3:使用sql server的统计函数
4:用group by子句实现分组的查询
A:多表查询和笛尔儿积
到目前为止,我们所用的都是单个表查询,但是在更多的情况的下,需要对多个表进行同时查询,这时可以把多个表的名字全部填写在from子句中.
比如:查询出每个职工的姓名,学历,所在部门名称.由于我们需要的结果来自于两个表,所以必须用多表查询
select 姓名,学历,部门名称,负责人 from work,部门 [分析为什么是错误的]
原因:问题出在对表格连接条件的限制上.在上面的语句中,没能对表格连接条件作任何限制,所以sql会在work表中每取出一条记录,就与部门表中的所有记录组合一次,那么假设work表有m条记录,而部门表中有n条记录,则得出的结果为m*n条记录这就是笛尔儿积,所以笛尔儿积返回的大多数的结果是冗余的、无用的,所以应该避免笛尔儿积的产生.
解决笛尔儿积的方法:事实上由于笛尔儿积是因为两个表的连接条件没有限制造成的,所以只要我们对两个表的连接进行条件限制,就可以避免笛尔儿积的产生.可以通过一个where子句,来连接两个表的公共的字段就可以了.
所以将上面的语句改成:select 姓名,学历,部门名称,负责人 from work,部门 where work.部门编号=部门.部门编号
B:使用表格的别名
A:当使用多个表进行查询时,如果有两个表中有相同的列,应该指明选中的是哪个表中的列.
比如:在work表检索出在address表中都有的职工的职工号,姓名,学历,基本工资
select 职工号,姓名,学历,基本工资 from work,address where work.职工号=address.职工号
上面的语句是错误的,原因是对于work和address表都有职工号,姓名列,所以应该指明是哪个表的职工号和姓名.
改成:select work.职工号,work.姓名,学历,基本工资 from work,address where work.职工号=address.职工号
或者:select address.职工号,address.姓名,学历,基本工资 from work,address where work.职工号=address.职工号
想一想:为什么对于学历,基本工资没有指明表名:即:work.学历,work.基本工资[只有一个表有这些列]
B:允许使用别名来访问表.
格式:1:表名 as 别名
2:表名 别名
例如:上面的语句可改写成:
select w.职工号,w.姓名,学历,基本工资 from work as w,address as a where w.职工号=a.职工号
上面的语句中在from中引用两个表,并且为表work指明了别名w,为表address指明了别名a,所以就可以用w来代表work表,用a来代表address表.或者省略as直接改成:select w.职工号,w.姓名,学历,基本工资 from work w,address a where w.职工号=a.职工号
C:如果使用了别名,则以后所有查询语句中,都必须使用别名列
比如:select work.职工号,work.姓名,学历,基本工资 from work w,address a where w.职工号=a.职工号 [是错误的]
C:使用统计函数:
sql跟我们提供了以下几个统计函数:
sum:返回一个数字列的总和
avg:对一个数字列求平均值
min:对一个数字列求最小值
max:对一个数字列求最大值
count:返回满足select语句中指定的条件的记录个数
举列:1:求出work表中所有男职工的基本工资的和
select sum(基本工资) as 性别为男的基本工资 from work where 性别=\'男\'
2:求出work表中所有职称是经理的最高工资和最低工资,平均工资
select max(基本工资) as 最高工资,min(基本工资) as 最低工资,avg(平均工资) as 平均工资 from work
3:与统计函数一起使用distinct关键字[通常只与count函数使用]
例:1:检索出work表中学历的个数
select count(学历) from work
2:检索出work表中学历的种类的个数
select count(distinct 学历) from work
试一试:select distinct count(学历) from work 可行否?
3:有work和部门表,检索出在销售部工作的员工的个数
select \'销售部的人数\'=count(职工号) from work a,部门 b
where a.部门编号=b.部门编号 and b.部门名称=\'销售部\'
4:在work表中检索出其基本工资小于职工平均工资的人数
select count(职工号) as 人数 from work
where 基本工资<(select avg(基本工资) from work)
5:有学科表和学费表,从学费表检索出有多少个学网页设计的人
select count(学号) as 网页设计的人数 from 学费 a,学科 b
where a.所学专业代号=b.课程编号 and b.课程名称=\'网页设计\'
D:使用group by子句对结果进行分类[只用于统计函数]
举列:1:检索出work表各职称的人数.
select 职称,count(职称) as 职称人数 from work group by 职称
2:检索出各学历的平均工资.
select 学历,avg(基本工资) from work group by 学历
3:有学科表和学费表,要求统计出各学科的学生数目.
select 所学专业代号,count(所学专业代号) as 人数 into #abc from 学费 group by 所学专业代号
select 课程名称,人数 from #abc,学科 where 所学专业代号=课程编号
4:有职工表和商品销售表,要求检索出每个职工的职工号,姓名,销售总量.
select 职工号,sum(销售量) as 销售总量 into #abcd from 商品销售 group by 职工号
select 职工.职工号,姓名,销售总量 from 职工,#abcd where #abcd.职工号=职工.职工号
5:查询出每个部门最高的基本工资,显示部门名称和最高基本工资
select 部门名称,max(基本工资) from work group by 部门名称
说明:1:在group by中不支持对列名的分配的别名
select 学历 as 职工学历,count(学历) from work group by 职工学历 [错错]
改为:select 学历 as 职工学历,count(学历) from work group by 学历
2:select后面每一列数据除了在统计函数中的列以外都必须在group by子句出现
比如:select 学历,性别,sum(基本工资) from work group by 学历[错错]
改为:select 学历,性别,sum(基本工资) from work group by 学历,性别
意义:各学历各性别的基本工资之和
评论