元函數在SQL查詢中應用實例分析【續上篇】

3. 實例分析                                                                
  爲了說明以上引入的特徵函數在加速查詢處理中的作用,讓我們具體分析一個實例。    
  試考察一個描述學生收
selfincome)(8)
入狀況的表 Students(name,s

tatus,parentincome,

  其中name是主鍵,屬性
自父母,當status取值0時
得到形如(name,income)
0值時)或是來自父母的收
status是一種標法量,當status
,表明學生的收入完全是自己勞
的查詢結果,其中income或爲學
入(當相應的status取值爲1時
取值1時,表明學生的收入完全來
動所得。針對這個表,假定我們想
生自己的收入(當相應的status取
)。
  從表students的結構及查詢結果的語義分析,完成查詢的常規方法應當是      
  SELECT name,income=parentincome                
  FROM student                                                      
  WHERE student=1 UNION (9)                            
  SELECT name , income=selfincome                
  FROM student                                                      
  WHERE student=0                                                
  這是一個很自然、很直白的查詢表達
執行這個查詢的一般過程是:首先分別執
存放查詢中間結果的臨時表並將兩個子查
序以便消除可能存在的重複值。至此,才
students要遍歷兩次而且要對中間結果作
的。查詢(9)唯一的優點,是它表達上
,但同時也是一個非常低效和非常耗費資源的表達。
行由算子UNION所連結的兩個子查詢,然後產生一個
詢的結果存入以這個臨時表中,第3步對臨時表作排
得到最終的查詢結果。在這樣的處理中,除對整個表
排序處理,處理上的煩雜和資源的消耗都是顯而易見
的自然直白,誰都想得到。
  對本例而言,還有更緊湊和更有效的查詢表達。例如,不難驗證以下的查詢            
  SEIECT name,income=parentincome
*status+selfincome*(1-status)
  FROM students; (10)                                        
  從語義上與查詢(9)
,因爲它只遍歷一次表stud
果,不同的查詢表達在處理
式,不但是必要的而且是可
完全等價。但查詢(10)不但消
ents而且避免了可怕的排序操作
效率和資源消耗上可能會相去甚
行的。
耗的存儲少而且處理上要有效得多
。這個例子說明,對同一個查詢結
遠。因此,尋求有效的查詢表達方

  查詢表達(10)與像(
子句和算子UNION顯式給出
查詢表達採用什麼形式,本
表達(10),不難發現只所
問題稍作些許改變(例如,
,如此等等)問題就不會這
們對任何顯式表達在WHERE
案是肯定的,這就是我們在
9)那樣的常規表達不同之處在
,首者將查詢條件間接地隱藏在
例都屬於“條件檢索”的查詢類
以能給出如此簡潔而正確的回籤
屬性student取0和1以外的值,
麼簡單了。因此,是否有一種很
子句和相關算子中的選擇條件找
下面要介紹的“特徵函數法”。
於,後者的查詢條件由兩個WHERE
SELECT子句的算術表達式中。無論
型。如果對照一下查詢要求和查詢
,實在是有點“事有湊巧”。如果
或者student取兩個以上的標法值
一般、很系統的解決方案,能讓我
到與之語義等價的算術表達式?答


  4. 幾個典型查詢的特徵函數解                                                
  正如上面所講,特徵函數能夠實現我
因此,特徵函數最直接和簡便的運用是針
爲了較全面地瞭解特徵函數在解決複雜查
例。對某些實例,我們還將說明它的應用
的特徵函數都沒有用元函數展開。因此,
(5)、(6)替換這裏的特徵函數。
們的願望,即將顯式的布爾條件轉化爲標量表達式。
對條件檢索型的查詢,但它的作用並不僅僅止於此。
詢中的作用,本節將由易到難介紹和分析若干典型實
領域。爲了表達上更緊湊,所有出現在標量表達式中
如果要通過實際運行驗證這裏的實例,必須先藉助於


  4.1 條件檢索                                                              
  由(10)給出的查詢可藉助於特徵函數識爲                                      
  SELECT name,                                                      
  income=parentincome
*d [status=1]+selfincome
*d [status=0]
  FROM student (11)                                            
  如果檢索條件僅止於此
檢索條件遠比此處複雜而多
外,加上按學生的年齡分段
依靠父母的學生爲一組,凡
三組。在查詢結果中,收入
母的收入和學生自己的收入
於用常規方法處理查詢的人
相對於原問題而言,要求的
,用(11)代替(10)並沒有什
樣。例如,若將上例的要求稍作
的要求,即以19歲和23歲爲年齡
年齡超過23歲者完全自食其力的
(income)一欄有不同的含義:
,對第三組學生,則對應於前兩
看來,這樣的條件就顯得大複雜
擴展是很輕微的。對照查詢表達
麼本質上的意義。但實際問題中的
修改,即在保留status原有語義而
的分界點,凡年齡不超過19歲而且
學生爲第二組,所有其他學生爲第
對前兩組學生,分別對應於他們父
組學生收入的算術平均值。在習慣
了。實際上,這是很自然的要求,
式(11),不難驗證

  SELECT name,                                                      
  income=parentincome*d [atatus=1]*d [age<=19]+selfincome*sign (d [status=O]+d [age>23])+( (parentinceome+selfinco me)/2.0*(1一d [status=1])*d [age<=19]-sign(d [sign=0] +d [age>23])

  FROM students; (12)                                        
  正是上述查詢所要求的有效表達方式
一一對應,都具有很典型的級聯式IF&#0;
,無論查詢條件多複雜(例如有更多的屬
等等),條件檢索型的查詢都具有如(11
件越多則級聯數越多,但正則算術表達式
只對表student遍歷一次。相反,若按常
來回答,最終的結果是所有子查詢結果往
瞭然。
。從income的表達形式看,與查詢條件的要求完全是
THEN&#0;ELSE結構。一般而言,在特徵函數的參與下
性出現在條件中,同一屬性值被劃分爲更多的區段,
),(12)那樣的典型結構。不同之處僅僅在於,條
的邏輯結構都相同。所有這類查詢表達,在執行中都
規方法求解,原則上每一個分類條件需要一個子查詢
UNION運算所得。兩種表達兩種效果,孰優孰劣一目


  4. 2 直方圖問題                                                          

  求直方圖是統計應用中
,用常規方法求解並不是一
處理的過程很高效而且很直
在表employee(name,age
如(nokids,onekids,few
、有一個孩子的、有兩個或
經常要解決的問題白如果統計數
個很輕鬆的任務。但是,借用特
觀。爲了說明這一點,讓我們看
dept,kids)中,其中kid也表
kids,manykids)的統計結果,
三個孩子的以及有三個以上孩子
據來自數據庫而且數據量很大的話
徵函數可以順利地解決問題,不但
一個具體的例子。假定統計數據存
示每個僱員的子女數。要求給出形
即分別計算出所有僱員中沒有孩子
的僱員總數。

  如果用常規方法,需要查歷表employ
manykids的值,然後經3個UNION運算才能
分爲4個區段而是8個甚至更多個區段,常
問題的解顯然是
ee四次,分別計算出nokids,onekids,fewkids和
得出最終的結果。如果原問題不是將僱員的子女數劃
規方法的低效就更明顯不過了。運用特徵函數,上述


  SELECT nokids=SIJM(d [kids=0]),                
  Onekids=SUM(d [kids=1])                                
  fewkids=SUM(d [2<=kids<=3])

  manykids=SUM[kids>=4])

  FROM employee; (13)                                        
  這個查詢結果的正確性很容易驗證:對於表中任意一行,如果kids=0,則d [kids=0]=1而且d [kids=l]=d [kids>=4]=d [2<=kids <=3]=0,所以該行在區段nokids中求和而不在任何其他三個區段中求和,對於kids的其他取值依此類推,這表明(13)的結果正是原問題所需要的結果。重要的是這個結果不但正確,得到這個結果的途境非常有效,因爲處理中只遍歷表一次。如果將僱員所擁有的子女數區分爲更多的值段,運用特徵函數的查詢處理仍然只遍歷表一次而不是更多,不同之處僅在於選擇表中的計算多幾項而已,查詢表達在邏輯上的複雜性一點也沒有增加。

  同一個基本問題也可以
問題往往很困難。
引導出不同的變異。若沒上述的

基本解作基礎,直接解決這些變異

  變異問題之一:對同一
要求得到如(dept,nokids
個表employee,按僱員所在的不
,onekid,fewkids,manykids
同部門分別計算子女數的分佈,即
)的結果。
  這個問題的解顯然是以下的查詢表達                                              
  SELECT dept.                                                      
  nokids=SUM(d [kids=0]),                                
  onekid=SUM(d [kids=1])                                  
  fewkids=SUM(d [2<=kids <=3]

  manykids=SUM(d [kids>=4])

  FROM employee;GROUP BY dept; (14)            
  變異問題之二:按照年齡區段求僱員
個區段,即:小於25歲的、大於45歲的以
2年齡段。這個問題事實上是要求對錶emp
fewkids,manykids)的結果,其中
子女分佈的直方圖。爲確定起見,僱員的年齡分爲三
及年齡在25歲到45歲之間的,分別稱爲第1、第3和第
loy回給出形如(ageCategoy,nokids,onekids,


  1 若age<25

  d (a)= 2 若25<=age<=45 3 若age>45

  (15)                                                                      
  這個問題雖有相當的難
Sybase的Transact SQL就是
需要的解答
度,但對於允許表達式出現在GR
如此),答案也是直接了當的。

OUP BY子句中的系統(例如,
不難驗證以下查詢表達正是我們所


  SELECT ageCategory=1xd [age<25]+2×d [25<=age<=45] +3×d [age>45],

  nokids =SUM(d [kids=0]),                              
  onekids =SUM(d [kids=1]),                            
  onekid =SUM( d [kids<=3 AND Kids>=2])

  manykids =SUM(d [kids>=4])

  FROM employee                                                    
  GROUP BY 1′ d [age<25]+2×d [25<=age<=45]+ 3×d [age>45]; (16)

  這個問題與上一個問題的區別僅僅在
ageCaegory,按照(15)式的定義,很容
選擇表和GROUP BY子句中使用3年齡段表達式
易驗證(16)確是我們所需要的查詢。

  沿着這個思路走下去,還可以處理更
有效性也越能顯現出來。
複雜的問題。當直方圖越來越“寬”時,特徵函數的


  4.3 錶轉置                                                                
  錶轉置是一個變換過程
設計中經常遇到的問題。C
Date將中文中前一種形式的
示。鑑於SQL的集函數本質
用集函數的給應用處理帶來
主意。
,它將一個窄而長的錶轉化成一
.j Date很早就注意到這一點並
表稱之爲表的“列式”表示,而
上是面向列式表示而不是面向行
靈活性的優點。因此,基表的設

種寬而短的表,這是在數據庫應用
給出了處理這一問題的一般原則。
將後一種形式的表稱爲“行式”表
式表示的,所以列式表示有便於運
計多考慮採用列式表示一般是個好


  針對列式表示的基表作
僱員月獎金的表bonus(nam
示,例如就可以寫成bonus
獎金一覽表,從bonus'表查
他的查詢要求很難有適應性
回籤其他處理要求。例如,
查詢時,特徵函數是實現錶轉置
e,month,amount)。這個表顯
’(name, janAmount,…,decAm
詢最簡便。但這種行式表示的表
。相反,形如bonus的列式表示
針對上述要求的特徵函數表示就
的有力主具。例如,考察一個記錄
然是列式表示,相對於它的行式表
ount)。如果想得到每個僱員各月
本質上只對這一種查詢有效,對其
不僅可以回答上述查詢而且還可以


  SELECT name,                                                      

  janAmount=SUM(amount×d [month=1]),          
  febAmount=SUM(amount×d [month=2]),          
  . . . .                                                                
  decAmount=SUM(amount×d [month=12])          
  FROM bonus                                                          
  GROUP BY name; (17)                                        
  讀者不妨思考一下,針對bonus表的同一查詢要求若不採用特徵函數該怎麼滿足。  

  4.4 求中位數                                                              
  在實驗數據處理中,經常有求一組數
位數,存在兩種定義,即統計學定義和所
是這組數中的某一個。因此,當有偶數個
,要視具體應用背景而定。中位數的後一
果數值的個數爲奇數(設爲n),則中位
的定義,用一個語句求一組數的中位數始
用一般方法來處理這個問題,也得寫一個
這個問題的一個很簡潔的解。爲確定起見
這組數據中不存在重複的值。除此而外,
假定下,數據集data的中位數正是下述查
據的“中位數”(median的要求。衆所周知,關於中
謂的“財務”定義。按照統計學的定義,中位數必須
數時,必須從兩個數中作出選擇,或選大者或選小者
種定義取兩數(在有偶數個數時)的算術平均值。如
數就是數組中第(n+1)/2個數。不論採用什麼樣
終是一個難題。既使是訓練有素的SQL程序員,要想
很複雜的過程。但是,借用於特徵函數,很容易得到
,考慮這樣的一組實驗數據data (value)。這表明
我們還要假定所有的數據都是非空的數據。在這樣的
詢語句的結果:

  SELECT x.value FROM data x, data y          
  GROUP BY x.value                                              
  HAVING SUM(d [y.value<=x.v
alue])=(COUNT(×) +1)/2 (18)
  因爲,對於每個x.value,表達式SUM(d [y.value<=x.value])的結果是數據集中小於或等於該值數據的個數,所以由這個HAVING子句選擇的正是所要求的中位數(細心的讀者不難發現,我們這裏利用了Sybase兩個整數相除的結果是實際相除後再取截斷而得到的值。另外,當數據集包含偶數個元素時,取的數是兩數中較小的一個,這正符合中位數的統計學定義。)


  上面求中位數的方法很
考察數據集data 2(partit
以是任意數據類型,整個數
是各個子集的中位數:
容易延拓到數據集往某些屬性而
ion,value),其中value仍爲非
據集data2經此屬性而分割爲若

分割爲若干個子集的情形。例如,
空數值量,但屬性partition則可
幹個子集。下述查詢語句的結果恰


  SELECT x.partition,x.value                          
  FROM data2 x,data2 y                                      
  WHERE x. partition=y. Partition                
  GROUP BY x.Partition , x.value                  
  HAVING SUM (d [y.Value<=x.value])=(COUNT(x)+1) /2 (19)

  上式中的自連結是表分割的需要,除此而外上兩種方法沒有本質上的區別。            

  4.5 求端值                                                                
  在某些實際問題中,所
將求這些數據項中取值最大
sat2),其中sat 1和sat 2
成績的一覽表,即求形如(
最好成績。
設計的表的行數據包含了若干個
或最小的稱爲“端值問題”。例
代表學生兩次考試的成績。假定
name,bestSat)的結果,其中b

可以彼此比較分析的數據項。我們
如,考察表scores(name,sat1,
需要得到每個人兩次考試中的最好
estSat表示每個學生兩次成績中的

  某些數據庫系統(例如Oracle)有內部函數greatest(value 1,value 2…),可供直接解決問題。在不具備這種函數的系統(例如Sybase等)中,一般解決方法是,第一次遍歷全表得以滿足條件,sat 1>=sat 2的sat 1,第二次遍歷全表得到滿足條件sat 2>sat l的sat 2,再將中間結果經UNION運算才能獲得最終結果。

  藉助於特徵函數只須掃描表一遍而且查詢表達非常簡單,即:                        
  SELECT name,                                                      
  bestSat=sat 1% d [sat 1>=sat 2]+sat 2×d [sat 2>sat1]

  FROM score; (20)                                              
  假定我們不只要得到每
所得,只須在(20)的選擇
個學生兩次考試中的最好成績,
表中補加一項,即:
而且還想知道這個成績是哪次考試

  SELECT name                                                        
  bestSat=sat l % d [sat1>=sat 2]+sat 2% d [sat 2>sat 1] whichSat=1% d [sat 1>=sat 2]+2% d [sat 2>sat l]

  FROM score; (21)                                              
  這個結果只在sat 1=s
所得)。除此而外似乎不必
興趣的讀者不妨考慮一下這
at2 時有點歧義但並不錯(在這
再做任何解釋了。以上只考慮了
個問題的種種變異情況及其解答
種情況下,(21)認爲是第一次考試
最大值,求最小值可仿此辦理。有


  5 幾個值得進一步思考的問題                                                  
  由(5)式給出的特徵
函數,在計算的複雜性上會
改善特徵函數的效率。其次
,是爲了保證元函數abs(
在着降低這一條件強度的可
,去掉非空假定就顯得特別
函數表示,並不是唯一的形式,
有差異。因此,選擇具有更低計
,本文開頭關於出現在特徵函數
)和sign()有定義和整個(5
能性。考慮到幾乎所有的主流數
必要了。
還可有其他的表現形式。不同的元
算複雜性的函數,有可能更進一步
中的屬性必須是非空數值量的假定
)式正確的充分性條件。所以,存
據庫系統都支持三值邏輯(3VL)

  儘管本文只考慮了特徵函數在查詢中
作較系統的考察。另外,在E.birger等
方面(例如,出現在特徵函數中的屬性,
象數據類型等等)。所有這些,都有待於
的作用,我們認爲同樣的思想也應當針對數據庫更新
人原始工作的框架內,也存在着種種明顯的可擴充的
既可以是普通的表屬性,也應當允許是某種受限的抽
我們更進一步的工作去挖掘或作出分析判斷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章