第 15 章
shicomnt_id
having sum(case when order_complete = 'N' then 1
else 0
end) =0
还有更简单的方法。使用另一个聚合函数,而不必转换任何的flag值。注意,从字母的顺序来看,
“Y” 大于“N”,如果所有的值都是“Y”,则最小值就是“Y”。于是:
select shicomnt_id
from orders
group by shicomnt_id
having min(order_complete) = 'Y'
这个方法利用了“Y”大于“N”,而没有考虑标志转换为数值。本方法更高效。
上例使用了group by,并以order_complete 值最小作为查询条件,那么,其中不同的子查询(或
作为子查询替代品的聚集函数)之间是如何比较的呢?如果先做sumcāo作而后检查总和是否为
0,必然导致整个orders 表排序。而上例中使用了不太常见的聚合函数min,一般比其他查询快,
其他查询因访问两个表(shicomnts 和orders)而速度较慢。
先前的例子大量使用了having 子句。如第4章所述,“粗心的SQL语句”往往和在聚合语句中使
用having 子句有关。下面这个查询(Oracle)就是一例,它要查询过去一个月内每个产品的每
周销售情况:
select product_id,
trunc(sale_date, 'WEEK'),
sum(sold_qty)
from sales_history
group by product_id, trunc(sale_date, 'WEEK')
having trunc(sale_date, 'WEEK') >= add_month(sysdate, -1)
这里的错误在于,having子句中的条件没有使用聚合。于是,DBMS必须处理sales_ history中的
每条记录,进行排序cāo作、进行聚合cāo作……然后过滤掉过时的数值,最后返回结果。这类错
误并不引人注意,直到sales_history表数据量变得非常大为止。当然,正确的方法是把条件放
在where 子句中,确保过滤会发生在早期阶段,而之后要处理的数据集已大为减小。
必须指出:对视图(即聚合的结果)应用条件时,如果优化器不够聪明,没有在聚合前再次注
入过滤条件,我们就会遇到完全相同的问题。
有些过滤条件生效太晚,应该提前,可做如下修改:
select custcomr_id
from orders
where order_date < add_months(sysdate, -1)
group by custcomr_id
having sum(amount) > 0
在这个查询中,以下having 的条件乍看起来相当合理:
having sum(amount) > 0
然而,如果amount 只能是正数或零,这种having 用法就不合理。最好改为:
where amount > 0
此例中,group by的使用分两种情况。首先:
select custcomr_id
from orders
where order_date < add_months(sysdate, -1)
and amount > 0
group by custcomr_id
我们注意到,group by对聚合计算是不必要的,可以用distinct 取代它,并执行相同的排序和消
除重复项目的工作:
select distinct custcomr_id
from orders
where order_date < add_months(sysdate, -1)
and amount > 0
把条件放在wher e 子句中,能让多余的记录尽早被过滤掉,因而更高效。
总结:聚合cāo作的数据应尽量少。
-------------------------------------------------------
访问小说分享者(剁椒鱼头)的书库,阅读更多TA分享的书籍!
地址:http://www.16sy.com/u?id=14
也可以百度搜索松语文学或者访问www.16sy.com
-------------------------------------------------------
松语文学免费小说阅读_www.16sy.com
having sum(case when order_complete = 'N' then 1
else 0
end) =0
还有更简单的方法。使用另一个聚合函数,而不必转换任何的flag值。注意,从字母的顺序来看,
“Y” 大于“N”,如果所有的值都是“Y”,则最小值就是“Y”。于是:
select shicomnt_id
from orders
group by shicomnt_id
having min(order_complete) = 'Y'
这个方法利用了“Y”大于“N”,而没有考虑标志转换为数值。本方法更高效。
上例使用了group by,并以order_complete 值最小作为查询条件,那么,其中不同的子查询(或
作为子查询替代品的聚集函数)之间是如何比较的呢?如果先做sumcāo作而后检查总和是否为
0,必然导致整个orders 表排序。而上例中使用了不太常见的聚合函数min,一般比其他查询快,
其他查询因访问两个表(shicomnts 和orders)而速度较慢。
先前的例子大量使用了having 子句。如第4章所述,“粗心的SQL语句”往往和在聚合语句中使
用having 子句有关。下面这个查询(Oracle)就是一例,它要查询过去一个月内每个产品的每
周销售情况:
select product_id,
trunc(sale_date, 'WEEK'),
sum(sold_qty)
from sales_history
group by product_id, trunc(sale_date, 'WEEK')
having trunc(sale_date, 'WEEK') >= add_month(sysdate, -1)
这里的错误在于,having子句中的条件没有使用聚合。于是,DBMS必须处理sales_ history中的
每条记录,进行排序cāo作、进行聚合cāo作……然后过滤掉过时的数值,最后返回结果。这类错
误并不引人注意,直到sales_history表数据量变得非常大为止。当然,正确的方法是把条件放
在where 子句中,确保过滤会发生在早期阶段,而之后要处理的数据集已大为减小。
必须指出:对视图(即聚合的结果)应用条件时,如果优化器不够聪明,没有在聚合前再次注
入过滤条件,我们就会遇到完全相同的问题。
有些过滤条件生效太晚,应该提前,可做如下修改:
select custcomr_id
from orders
where order_date < add_months(sysdate, -1)
group by custcomr_id
having sum(amount) > 0
在这个查询中,以下having 的条件乍看起来相当合理:
having sum(amount) > 0
然而,如果amount 只能是正数或零,这种having 用法就不合理。最好改为:
where amount > 0
此例中,group by的使用分两种情况。首先:
select custcomr_id
from orders
where order_date < add_months(sysdate, -1)
and amount > 0
group by custcomr_id
我们注意到,group by对聚合计算是不必要的,可以用distinct 取代它,并执行相同的排序和消
除重复项目的工作:
select distinct custcomr_id
from orders
where order_date < add_months(sysdate, -1)
and amount > 0
把条件放在wher e 子句中,能让多余的记录尽早被过滤掉,因而更高效。
总结:聚合cāo作的数据应尽量少。
-------------------------------------------------------
访问小说分享者(剁椒鱼头)的书库,阅读更多TA分享的书籍!
地址:http://www.16sy.com/u?id=14
也可以百度搜索松语文学或者访问www.16sy.com
-------------------------------------------------------
松语文学免费小说阅读_www.16sy.com