最近,同事需要查询用户的业务并报告来自多个表的数据,并编写一个缓慢的SQL语句:


选择
美国的名字,
S.AccountantCode,
(
从(*)*(*)(*)*(*)中选择(*)
选择不同的businessbackupid从biz_businessbackupcustomer(在那里Id
选择从哪里businessbackupcustomerid rpt_registform(signaturecpa1id = s.id或signaturecpa2id = s.id)和docstatus = 30
t))
as'bnum),
(当R. Id空0其他1端)as'num,
r.reportbackupdate
从
base_staff S
左连接rpt_registform R(r.signaturecpa1id = s.id或r.signaturecpa2id = s.id)和r.docstatus = 30
在s.usertype = 3


查询需要执行大约10秒。经过仔细分析,它有2个查询结果相似的结果集(base_staff,rpt_registform相关部分),这是CTE的应用场合。

从SQLServer系列的书,让我们了解英语的概念:

MS的帮助: / / / ms.sqlsvr ms.sqlcc。V10,V10。ZH CHS / / / 27cfb819-3e8d-4274-8bbe-cbbe4d9c2e23.htm s10de_6tsql HTML

指定临时命名的结果集,这就是所谓的公用表表达式(CTE)。这个表达来自一个简单的查询和在一个单一的选择,插入,更新,合并执行的范围界定,或删除的声明。这一条款也可用于创建视图的语句作为选择定义语句的声明的一部分。公共表表达式可以包含引用自身。这种表达称为递归公用表表达式。

以下是CET重写后的查询:


与热膨胀系数为
(
选择
--s.id作为s_id,
S.Name, s.AccountantCode,
r.businessbackupcustomerid -- ID作为r_id,r.signaturecpa1id,r.signaturecpa2id
从base_staff S
左连接rpt_registform R
在(r.signaturecpa1id = s.id或r.signaturecpa2id = s.id)和r.docstatus = 30
在s.usertype = 3
)
选择T0 *
(。
从(*)*(*)(*)*(*)中选择(*)
选择不同的businessbackupid
从biz_businessbackupcustomer B
内部联接CTE ID = cte.businessbackupcustomerid B.
在t0。accountantcode = cte.accountantcode
T1)
)公约的数目
从
(
选择的名字,accountantcode,计数(businessbackupcustomerid)作为报告编号
从热膨胀系数
集团的名字,AccountantCode
T0)


执行此查询只需要5秒,是原始查询的两倍。

注意上面的计数函数,它计算一列,如果列是一行中的NULL,它不会计算行,这是符合要求的。

此外,CTE还可以进行递归处理,详细介绍上述联机丛书URL的内容。