图片 4

SqlServer 表单查询问题及缓慢解决方法

Q1:表StudentScores如下,用一条SQL语句查询出每门课都大于80分的学生姓名

1   概述

Q2:表DEMO_DELTE如下,删除除了自动编号不同,其他都相同的学生冗余信息

已发布【SqlServer系列】文章如下:

Q3:Team表如下,甲乙丙丁为四个球队,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合

  • 【SqlServer系列】SQLSERVER安装教程 

  • 【SqlServer系列】数据库三大范式

  • 【SqlServer系列】表单查询
  • 【SqlServer系列】表连接
  • 【SqlServer系列】子查询
  • 【SqlServer系列】远程访问
  • 【SqlServer系列】集合运算

Q4:请考虑如下SQL语句在Microsoft SQL Server 引擎中的逻辑处理顺序

如下几个问题,如果你能解决,请继续往下看,若不能解决,请先复习SQL基础知识,再来阅读本篇文章。本篇文章深度中等左右。

USE TSQLFundamentals2008SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numordersFROM Sales.OrdersWHERE custid=71GROUP BY empid,YEAR(orderdate)HAVING COUNT(*)1ORDER BY empid,orderyear

Q1:表StudentScores如下,用一条SQL语句查询出每门课都大于80 分的学生姓名

本篇文章将剖析一般查询过程中,涉及到的处理逻辑子句,主要包括FROM,WHERE,GROUP
BY,HAVING,SELECT,ORDER BY,TOP,OVER等子句。

图片 1

2 SELECT语句的元素

Q2:表DEMO_DELTE如下,删除除了自动编号不同, 其他都相同的学生冗余信息

2.1 常规查询子句和逻辑处理顺序

图片 2

对数据表进行检索查询时,查询语句一般包括FROM,WHERE,GROUP
BY,HAVING,SELECT,ORDER BY,TOP,OVER等子句,请考虑如下例子的逻辑处理顺序。

Q3:Team表如下,甲乙丙丁为四个球队,现在四个球对进行比赛,用一条sql 语句显示所有可能的比赛组合

USE TSQLFundamentals2008SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numordersFROM Sales.OrdersWHERE custid=71GROUP BY empid,YEAR(orderdate)HAVING COUNT(*)1ORDER BY empid,orderyear

图片 3

如上代码,在SQL中逻辑处理顺序如下:

Q4:请考虑如下SQL语句在Microsoft SQL
Server 引擎中的逻辑处理顺序

USE TSQLFundamentals2008FROM Sales.OrdersWHERE custid=71GROUP BY empid,YEAR(orderdate)HAVING COUNT(*)1SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numordersORDER BY empid,orderyear
1 USE TSQLFundamentals2008
2 
3 SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numorders
4 FROM Sales.Orders
5 WHERE custid=71
6 GROUP BY empid,YEAR(orderdate)
7 HAVING  COUNT(*)>1
8 ORDER BY empid,orderyear

逻辑处理顺序可归结为如下:

本篇文章将剖析一般查询过程中,涉及到的处理逻辑子句,主要包括FROM,WHERE,GROUP
BY,HAVING,SELECT,ORDER BY,TOP,OVER等子句。

注释:

2   SELECT语句的元素

a.在常规编程语言中,如c++,java,c#等,程序按照“从上往下”的顺序一步一步地执行,然而在SQL中,SELECT语句所处位置虽然在最开始,却不是在最先执行的;

2.1
常规查询子句和逻辑处理顺序

b.逻辑处理顺序的每一步返回的结果集均是紧接着该步语句的下一步语句要执行的结果集;

对数据表进行检索查询时,查询语句一般包括FROM,WHERE,GROUP
BY,HAVING,SELECT,ORDER
BY,TOP,OVER等子句,请考虑如下例子的逻辑处理顺序。

c.FROM获取数据源(或者数据表),WHERE在FROM基础上过滤条件,GROUP
BY在WHERE的基础上按照至少一列对集合进行分组,HAVING在GROUP
BY基础上,对已经分组的集合进行过滤,SELECT语句在HAVING基础上检索,ORDER
BY在SELECT基础上按照一定条件进行排序;

1 USE TSQLFundamentals2008
2 
3 SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numorders
4 FROM Sales.Orders
5 WHERE custid=71
6 GROUP BY empid,YEAR(orderdate)
7 HAVING  COUNT(*)>1
8 ORDER BY empid,orderyear

2.2 部分查询子句讲解

如上代码,在SQL中逻辑处理顺序如下:

2.2.1 FROM子句

USE TSQLFundamentals2008

FROM Sales.Orders
WHERE custid=71
GROUP BY empid,YEAR(orderdate)
HAVING  COUNT(*)>1
SELECT empid,YEAR(orderdate) AS orderyear,COUNT(*) numorders
ORDER BY empid,orderyear

a.用数据库架构在限定代码中的对象名称,即使不用数据库架构限定,Sql
Server也会隐式解析它,代价更高,初次之外,如果对象名相同,没有架构限定,会产生歧义;

 逻辑处理顺序可归结为如下:

b.FROM * 性能比 FROM conum_name性能低;

图片 4

c.FROM查询得到的结果集顺序是随机的;

注释:

2.2.2 WHERE子句

a.在常规编程语言中,如c++,java,c#等,程序按照“从上往下”的顺序一步一步地执行,然而在SQL中,SELECT语句所处位置虽然在最开始,却不是在最先执行的;

a.过滤FROM阶段返回的行;

b.逻辑处理顺序的每一步返回的结果集均是紧接着该步语句的下一步语句要执行的结果集;

b.WHERE 谓词或逻辑表达式;

c.FROM获取数据源(或者数据表),WHERE在FROM基础上过滤条件,GROUP
BY在WHERE的基础上按照至少一列对集合进行分组,HAVING在GROUP
BY基础上,对已经分组的集合进行过滤,SELECT语句在HAVING基础上检索,ORDER
BY在SELECT基础上按照一定条件进行排序;

c.WHERE子句对查询性能有重要影响,在过滤表达式基础上,Sql
Server会计算使用什么索引来访问请求的数据;

2.2 
部分查询子句讲解

d.扫描整张表,返回所有可能的行,在客户端过滤,开销比较大,如产生大量的网络传输流量;

2.2.1   FROM子句

e.T-SQL使用三值谓词逻辑;

a.用数据库架构在限定代码中的对象名称,即使不用数据库架构限定,Sql
Server也会隐式解析它,代价更高,初次之外,如果对象名相同,没有架构限定,会产生歧义;
b.FROM * 性能比 FROM
conum_name性能低;
c.FROM查询得到的结果集顺序是随机的;
2.2.2  WHERE子句

2.2.3 GROUP BY子句

a.过滤FROM阶段返回的行;
b.WHERE 谓词或逻辑表达式;
c.WHERE子句对查询性能有重要影响,在过滤表达式基础上,Sql
Server会计算使用什么索引来访问请求的数据;
d.扫描整张表,返回所有可能的行,在客户端过滤,开销比较大,如产生大量的网络传输流量;
e.T-SQL使用三值谓词逻辑(true,false,unknown);

a.GROUP
BY阶段将上一阶段逻辑查询处理返回的行按“组”进行组合,每个组由在GROUP
BY子句中指定的个元素决定;

2.2.3  GROUP BY子句

b.如果查询语句中涉及到分组,那么GROUP
BY阶段之后测所有阶段的操作对象将是组,而不是单独的行。每个组最终表示为查询结果集中的一行;

a.GROUP
BY阶段将上一阶段逻辑查询处理返回的行按“组”进行组合,每个组由在GROUP
BY子句中指定的个元素决定;
b.如果查询语句中涉及到分组,那么GROUP
BY阶段之后测所有阶段(包括HAVING、SELECT以及ORDER
BY)的操作对象将是组,而不是单独的行。每个组最终表示为查询结果集中的一行;
c.GROUP
BY阶段之后处理的子句中指定的所有表达式务必保证为每个组只返回一个标量(单值)。以GROUP
BY列表中的元素为基础的表达式满足这一要求,因为按照定义,在每个组中GROUP
BY元素只唯一出现一次;
d.聚合函数只为每个组返回一个值,所以一个元素如果不再GROUP
BY列表中出现,就只能作为聚合函数(COUNT、SUM、AVG、MIN和MAX)的输入。(注意:若有GROUP
BY子句,聚合函数只操作具体的每组,而非所有组);
e.所有聚合函数都会忽略NULL,但COUNT(*)除外;
f.在聚合函数中,可以使用distinct来处理非重复数,如count(distinct
vary);

c.GROUP
BY阶段之后处理的子句中指定的所有表达式务必保证为每个组只返回一个标量。以GROUP
BY列表中的元素为基础的表达式满足这一要求,因为按照定义,在每个组中GROUP
BY元素只唯一出现一次;

2.2.4  HAVING子句

d.聚合函数只为每个组返回一个值,所以一个元素如果不再GROUP
BY列表中出现,就只能作为聚合函数的输入。;

a.HAVING子句用于指定对组进行过滤的谓词或逻辑表达式,这与WHERE阶段对单独的行进行过滤相对应;
b.因为HAVING子句是在对行进行分组后处理的,所以可以在逻辑表达式中引用聚合函数,如
HAVING
COUNT(*)>1,意味着HAVING阶段过滤器只保留包含多行的组;