在現實生活中,樹型資料屢見不鮮:組織機構,產品結構,人事關係等等......記得在以往的乙個專案中,涉及到機構,人員,在對其進行處理,特別是進行統計,聚集操作的時候,我一直沒找到乙個好的方法.臨時表,檢視,程式控制...能用的辦法都用上了,但在處理效率上一直不盡如人意.歸根結底,我的感覺就是在資料庫中,對資料的操作方式(不管是sql語言,sp,view...)不象程式語言那樣靈活,高效率.
cte(common table expression)是sql server 2005眾多新特性之一.他是乙個可以由定義語句引用的臨時命名結果集.他給我的感覺就是檢視,只不過使用起來更加簡單(不用在create view,drop view之類).更重要的,是他的遞迴功能,這也正是cte真正威力所在.下面就給出乙個簡單的例子.
在這個想象情形中,有類似如下的機構圖:
在資料庫中,建立兩個表:department(機構,部門表)和employee(員工表).表結構和測試資料如下:
department表:
employee表:
現假設如下情形:需要統計各部門(公司)人數的資訊(當乙個人屬於a部門,a部門屬於b公司,則在統計a部門和b公司時,都要把該人計算在內.).現在,我們就可以利用cte強大的遞迴功能:
withemploycte (departmentid)
as(
--base case(anchor member).get all employee
select
departmentid
from
employee
union
all--
recursive member
select
depart.parentid
from
department depart
join
employcte emp
ondepart.departmentid
=emp.departmentid
where
depart.parentid
isnot
null
)select
*from
department depart
--join all department
left
join
( select
employcte.departmentid,
count(*
) as
employeesum
from
employcte
left
join
department depart
ondepart.departmentid
=employcte.departmentid
group
byemploycte.departmentid) empsum
ondepart.departmentid
=empsum.departmentid
通過使用cte,統計每乙個機構(部門)的人數資訊現在只用一句sql語句就搞定了,是不是很令人激動呢:)現在,我們來看一看這條語句:首先,統計的思路是從每乙個人開始,得到乙個人所在的機構,然後遞迴的得到該機構的父機構直到頂級機構(類似於這個人所屬機構的乙個路徑).然後將這個人和路徑上每個機構關聯起來.所有,在sql中,先定義乙個cte----employcte,再定義這個cet遞迴的基(在這個例子中,是所有的員工).然後在遞迴部分,用部門表去連線這個cte本身(他們之間的關聯當然就是departmentid了.這樣,就得到了所有員工所屬機構的路徑.然後,在通過以部門為單位,做一次聚集,就得到了所有機構的人數統計資訊.(說得舌頭都卷了,其實直接看sql,很是簡單明瞭:).
順便,假如,統計每個部門的人數時候,不按照遞迴來統計(假如乙個人屬於a部門,a部門屬於b公司,則統計b公司時候不統計此人).利用cte也是相當簡單:
withdepartmenthierarchy (departmentid,departmentname,parentid,hierarchylevel)
as(
--base case
select
departmentid,departmentname,parentid,1as
hierarchylevel
from
department
where
parentid
isnull
union
all--
recursive member
select
depart.departmentid,depart.departmentname,depart.parentid,departhier.hierarchylevel +1
ashierarchylevel
from
department depart
inner
join
departmenthierarchy departhier
ondepart.parentid
=departhier.departmentid ),departandemp(departmentid,departmentname,parentid,hierarchylevel,num)
as(
select
*,employeenum=(
select
count(*
) from
employee
where
departmentid
=departmenthierarchy.departmentid)
from
departmenthierarchy)
select
*from
departandemp
在上面這個例子中,用到了兩個cte,在使用多個cte時,只用逗號將各個cte分開即可.
另外,在使用cte的過程中,也感覺到一些不方便的東西.例如:要想使用乙個cte,必須申明了他之後馬上使用,否則,其後任何使用,會報"invalid object"錯誤.有時我使用完某個cte後,想再使用一次,麻煩就出來了,鬱悶.也不知道ms是怎麼想的還是我沒找他其他辦法?還有,在cte的遞迴部分,不能使用諸如sum,count的聚集函式,這著實讓我鬱悶,不知道是處於實現上的原因還是效能上的原因.如果能使用的話,在做統計聚集的時候cte將會更加簡單方便
轉自:
利用SQL 2005 CTE處理樹型資料
在現實生活中,樹型資料屢見不鮮 組織機構,產品結構,人事關係等等.記得在以往的乙個專案中,涉及到機構,人員,在對其進行處理,特別是進行統計,聚集操作的時候,我一直沒找到乙個好的方法.臨時表,檢視,程式控制.能用的辦法都用上了,但在處理效率上一直不盡如人意.歸根結底,我的感覺就是在資料庫中,對資料的操...
sql 2005 迴圈處理資料
對oracle而言用游標很容易就可以實現,也不會太耗費資源 相對來說 而sql用游標確相當的慢,以下用row number實現的乙個迴圈處理 declare date datetime,maxid int id int begin select maxid count from nt fundchi...
SQL2005中利用儲存過程分頁
進行top查詢時 引數需要帶上 declare page int,pagesize int set page 2 select top page from usertb 分頁 select top 2 from usertb where userid not in select top 2 user...