在sqlserver中如何使用CTE解決復(fù)雜查詢(xún)問(wèn)題
最近,同事需要從數(shù)個(gè)表中查詢(xún)用戶(hù)的業(yè)務(wù)和報(bào)告數(shù)據(jù),寫(xiě)了一個(gè)SQL語(yǔ)句,查詢(xún)比較慢:
Select S.Name, S.AccountantCode, ( Select COUNT(*) from ( Select Distinct BusinessBackupId from Biz_BusinessBackupCustomer where Id in ( Select BusinessBackupCustomerId from Rpt_RegistForm where ( SignatureCPA1Id=S.Id or SignatureCPA2Id=S.Id ) and DocStatus=30 ) ) T ) as 'BNum', (case when R.Id is null then 0 else 1 end ) as 'Num', R.ReportBackupDate from Base_Staff S left join Rpt_RegistForm R on ( R.SignatureCPA1Id=S.Id or R.SignatureCPA2Id=S.Id ) and R.DocStatus=30 where S.UserType=3
該查詢(xún)需要執(zhí)行10秒左右,仔細(xì)分析,它有2次查詢(xún)類(lèi)似的結(jié)果集(Base_Staff,Rpt_RegistForm 關(guān)聯(lián)部分),這正是CTE應(yīng)用的場(chǎng)合。
從SQLSERVER 聯(lián)機(jī)叢書(shū),我們來(lái)了解下CET的概念:
ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-CHS/s10de_6tsql/html/27cfb819-3e8d-4274-8bbe-cbbe4d9c2e23.htm
指定臨時(shí)命名的結(jié)果集,這些結(jié)果集稱(chēng)為公用表表達(dá)式 (CTE)。該表達(dá)式源自簡(jiǎn)單查詢(xún),并且在單條 SELECT、INSERT、UPDATE、MERGE 或 DELETE 語(yǔ)句的執(zhí)行范圍內(nèi)定義。該子句也可用在 CREATE VIEW 語(yǔ)句中,作為該語(yǔ)句的 SELECT 定義語(yǔ)句的一部分。公用表表達(dá)式可以包括對(duì)自身的引用。這種表達(dá)式稱(chēng)為遞歸公用表表達(dá)式。
下面看看經(jīng)過(guò)CET改寫(xiě)過(guò)的查詢(xún):
With CTE as ( select --s.Id as S_ID, s.Name ,s.AccountantCode, r.BusinessBackupCustomerId --, r.Id as R_ID ,r.SignatureCPA1Id,r.SignatureCPA2Id from Base_Staff S left join Rpt_RegistForm R on ( R.SignatureCPA1Id=S.Id or R.SignatureCPA2Id=S.Id ) and r.DocStatus=30 where s.UserType=3 ) select t0.* ,( Select COUNT(*) from ( Select Distinct BusinessBackupId from Biz_BusinessBackupCustomer b inner join CTE on b.Id =CTE.BusinessBackupCustomerId where t0.AccountantCode=CTE.AccountantCode ) t1 ) as '約定書(shū)數(shù)' from ( select Name, AccountantCode,COUNT( BusinessBackupCustomerId) as '報(bào)告數(shù)' from CTE group by Name,AccountantCode ) t0
執(zhí)行此查詢(xún),只需要5秒鐘時(shí)間,比原來(lái)的查詢(xún)提高了一倍。
注意上面的Count函數(shù),它統(tǒng)計(jì)了一個(gè)列,如果該列在某行的值為NULL,將不會(huì)統(tǒng)計(jì)該行,這正符合需求。
另外,CTE還可以做遞歸處理,詳細(xì)見(jiàn)上面的聯(lián)機(jī)叢書(shū)URL的內(nèi)容說(shuō)明。
- sql server使用公用表表達(dá)式CTE通過(guò)遞歸方式編寫(xiě)通用函數(shù)自動(dòng)生成連續(xù)數(shù)字和日期
- SqlServer使用公用表表達(dá)式(CTE)實(shí)現(xiàn)無(wú)限級(jí)樹(shù)形構(gòu)建
- SQL Server 公用表表達(dá)式(CTE)實(shí)現(xiàn)遞歸的方法
- 使用SqlServer CTE遞歸查詢(xún)處理樹(shù)、圖和層次結(jié)構(gòu)
- SQL SERVER 2008 CTE生成結(jié)點(diǎn)的FullPath
- SQLSERVER2008中CTE的Split與CLR的性能比較
- 使用SQLSERVER 2005/2008 遞歸CTE查詢(xún)樹(shù)型結(jié)構(gòu)的方法
- SQL?Server使用T-SQL進(jìn)階之公用表表達(dá)式(CTE)
相關(guān)文章
數(shù)據(jù)庫(kù)備份 SQLServer的備份和災(zāi)難恢復(fù)
數(shù)據(jù)處理在現(xiàn)代企業(yè)運(yùn)營(yíng)中變得越來(lái)越重要,越來(lái)越關(guān)鍵,甚至?xí)蔀槠髽I(yè)發(fā)展的一項(xiàng)瓶頸. 數(shù)據(jù)保護(hù)的重要性也不言而喻. 如果一個(gè)企業(yè)沒(méi)有很好的數(shù)據(jù)保護(hù)方案或策略的話,一旦發(fā)生重要數(shù)據(jù)丟失,后果將會(huì)是災(zāi)難性的,伴隨著會(huì)有經(jīng)濟(jì)利益方面的損失.2010-07-07SQL server中字符串逗號(hào)分隔函數(shù)分享
繼SQl -Function創(chuàng)建函數(shù)數(shù)據(jù)庫(kù)輸出的結(jié)果用逗號(hào)隔開(kāi),在開(kāi)發(fā)中也有許多以參數(shù)的形式傳入帶逗號(hào)字條串參數(shù),需要的朋友可以參考下2016-10-10sql server判斷數(shù)據(jù)庫(kù)、表、列、視圖是否存在
這篇文章主要介紹了sql server判斷數(shù)據(jù)庫(kù)、表、列、視圖是否存在的方法,需要的朋友可以參考下2014-07-07分組后分組合計(jì)以及總計(jì)SQL語(yǔ)句(稍微整理了一下)
這篇文章主要介紹了分組后分組合計(jì)以及總計(jì)SQL語(yǔ)句,需要的朋友可以參考下2017-02-02SqlServer強(qiáng)制斷開(kāi)數(shù)據(jù)庫(kù)已有連接的方法
在執(zhí)行建庫(kù)腳本時(shí),往往會(huì)先將原有的數(shù)據(jù)庫(kù)drop掉,由于SqlServer檢測(cè)到有數(shù)據(jù)連接時(shí)禁止執(zhí)行drop database操作,所以建庫(kù)腳本經(jīng)常執(zhí)行失敗,為此我們需要一種能強(qiáng)制斷開(kāi)數(shù)據(jù)庫(kù)已有連接的方法,需要的朋友可以參考下2012-12-12SQL Server多表查詢(xún)優(yōu)化方案集錦
本文我們主要對(duì)SQL Server多表查詢(xún)的優(yōu)化方案進(jìn)行了總結(jié),并給出了實(shí)際的例子進(jìn)行性能與效率的對(duì)比,需要的朋友可以參考下2015-08-08SQL Server中統(tǒng)計(jì)每個(gè)表行數(shù)的快速方法
這篇文章主要介紹了SQL Server中統(tǒng)計(jì)每個(gè)表行數(shù)的快速方法,本文不使用傳統(tǒng)的count()函數(shù),因?yàn)樗容^慢和占用資源,本文講解的是另一種方法,需要的朋友可以參考下2015-02-02Sql Server里刪除數(shù)據(jù)表中重復(fù)記錄的例子
這篇文章主要介紹了Sql Server里刪除數(shù)據(jù)表中重復(fù)記錄的例子,本文給出了3種操作方法,需要的朋友可以參考下2014-08-08