查询逻辑处理顺序

select语句的目的是对表进行查询,应用一定的逻辑处理,并返回结果。
select语句中的元素
From子句
是逻辑处理阶段的第一个查询子句。用于指定要查询的表名,以及对这些表进行操作的表运算符。
where子句
可以指定一个谓词或逻辑表达式,从而过滤由from阶段返回的行。只有能让逻辑表达式结果为True的行,才能由where 阶段返回给后续的逻辑查询处理阶段。
where 后面不跟聚合函数。
group by 子句
将前面逻辑处理返回的行按’组’进行组合。每个组由group by子句中指定的元素决定。
如果查询涉及到分组,那么group by阶段后面的所有阶段(having,select,order by)的操作对象都是组,而不是单独的行。每个组最终也表示为查询结果集中的一行。
这意味着在group by 阶段之后处理的子句中指定的所有表达式务必保证为每个组只返回一个标量(单值)。
可以简单记忆:在对数据进行分组之后,查询为每个组只返回一行(每个组只能返回一个值)。

having子句
用于指定对组进行过滤的谓词或表达式,这与where阶段对单独的行进行过滤相对应。
因为having子句是在对行进行分组后处理的,所以可以在逻辑表达式中使用聚合函数。
select 子句
用于指定需要在查询返回的结果中包含的属性(列)。
select里面可以使用别名。<表达式>AS <别名>这种格式。
select子句是在from,where,group by,having 后面处理的。
这意味着对于select子句之前处理的那些子句,在select子句中为表达式分配的列名不存在。(在select之前这些列的别名其他子句不能使用)
order by子句
order by子句用于展示数据时对输出结果中的行进行排序。从逻辑查询处理来看,order by是最后处理的一个子句。
order by是唯一能够引用select处理阶段创建的别名列的阶段,因为它是唯一一个在select阶段之后被处理的阶段。
升序ASC,降序DESC
T-SQL 支持在order by子句中指定没有在select子句中出现过的元素。也就是说,排序依据的列并不一定必须要在输出返回的列中选取。
但是,当指定了distinct后,order by子句就被限制为只能选取在select 列表中出现的哪些元素。
原因是:当指定distinct时,一个结果行可能代表多个原始行,因此可能无法清楚的知道应该使用order by 列表中多个可能值的哪一个。
such as:
SELECT DISTINCT Country
FROM HR.EMPLOYEES
ORDER BY Empid
这个语句就是错误的,报错信息
–ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
(如果指定了select distinct,则order by items必须出现在选择列表中。)
可当把empid添加到查询列表中时,查询的结果又不是想要的,和上面说的原因一样
SELECT DISTINCT Country,empid
FROM HR.EMPLOYEES
ORDER BY Empid
在这里插入图片描述
正确的做法就是:(不使用order by)
select distinct country
from hr.employees

TOP 选项
top是T-sql中特有的,用于限制查询返回的行数或百分比。
当在查询中指定了order by 子句时,top将依赖该子句来定义行的逻辑优先顺序。

如果想让查询时确定性的,就要让order by列表能唯一的决定一行。换句话说:就是为order by 列表增加一个附加属性
tiebreakers 是一个允许唯一的排列元素的属性或属性列表,它不一定是单个属性。
返回所有具有相同结果的行
top(5)with ties
和distinct一起使用
top在distinct后面,distinct top(5)
还有top (5) percent

不能在同一个查询中即通过一个order by列表来为top选项决定各行的逻辑优先顺序,
同时还想用另一个order by对输出中的行进行排序以展示数据,根本不能这样用。
为了实现这个查询,就要使用表表达式(table expression)。

over 子句
over子句用于为行定义一个窗口,以便进行特定的计算。可以把行的窗口简单的认为是运算将要操作的一个行的窗口。

因为聚合函数和排名函数都是可以支持over子句的运算类型。由于over子句为这些函数提供了一个行的窗口,所以这些函数称之为开窗函数(window function).

聚合函数的要点就是对一组值进行聚合,聚合函数传统上一直以group by 查询作为操作的上下文。
聚合开窗函数使用over子句提供窗口作为上下文,对窗口中的一组值进行操作,而不是使用group by子句提供的上下文。这样就不必对数据进行分组,还能够在同一行中同时返回基础行的列和聚合列。

只有在select 和order by处理阶段才能使用over子句。

如果想对行进行限制或者区分,可以使用partition by子句。
比如:返回所有行的总价格和当前客户的总价格
select orderid,custid,val,
sum(val)over()as totalvalue,–总价格
sum(val)over(partition by custid) as custtotalvalue–当前客户
from sales.OrderValues;

over子句的优点就是返回基本列的同时,在同一行对他们进行聚合;
也可以在表达式中混合使用基本列和聚合值列。
select orderid,custid,val,
100.*val /sum(val)over()as pctall,
100.*val/sum(val)over(partition by custid) as pctcust
from sales.OrderValues;
(在表达式中使用的十进制数100.而不是直接使用整数100,因为这样可以隐式的将整数值val和sum(val)转换成十进制实数值,否则不会保留小数部分).

over 子句也支持四种排名函数:ROW_NUMBER(行号),RANK(排名),DENSE_RANK(密集排名),NTILE
ROW_NUMBER()函数是在distinct子句之前处理的。在同一select子句中不同时指定distinct和row_number是一条最佳实践原则,因为distinct子句在这种情况下不起任何作用。

注意:和聚合开窗函数不同的是,排名函数over子句里必须有order by,聚合函数可以为空。

所以上面子句的逻辑处理顺序
FROM
(可以在这加上join on)
WHERE
GROUP BY
HAVING
SELECT
OVER
DISTINCT
TOP
ORDER BY

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值