問:我的一個表中包含了名為idvalue的單列主鍵。對于給定的idvalue值,我希望找到緊鄰目標值之前和之后的表行(假定結果按idvalue排序)。怎樣才能不使用游標而通過一個基于集合的方法得到需要的結果?
答:transact-sql是一個基于集合的語言,使用它在結果集中定位特定的行并非一件易事。但是,服務器端ansi transact-sql游標的性能遠遠不如基于集合的解決方案,因此,學習解決問題的多種技術非常重要,尤其在面臨上述問題時。
以northwind數據庫中的orders表為例。我們可以這樣重述該問題:怎樣才能在orders表中找到緊鄰特定行之前和之后的行而不使用游標?假設我們按照orderid列對結果集排序。
創造性地使用sql server的min()、max()和 top功能可以幫助您解決諸如此類的結果集定位問題。程序清單1和2給出了兩個相似的、僅有細微差別的解決方法。程序清單1提供了一個常見的解決方案,因為它運用了@targetorder的min()和max()終點。但在某些情況下,展示top的靈活性也很有用。請注意,在以參數方式提供orders表的最小orderid(10248)時,程序清單2中的查詢將返回空集,因為該查詢假定在@targetorder行前總有一個行存在。
一般說來,生成結果集的方法不止一種,其中某一方法通常比其他的更高效。當您對這兩個例子評估showplan和set statistics io信息時,您會發現運用了top語句的程序清單2的效率略微高于程序清單1。差別很細微的原因在于樣本數據集很小,但在存在多種查詢方法的情況下,測試不同方法的性能非常重要。
—brian moran
程序清單1:使用包含or關鍵字的min() and max()函數查找目標行
declare @targetorder int
set @targetorder=10330
from orders
where [email protected]
or orderid=(select max(orderid)
from orders where orderid < @targetorder)
or orderid = (select min(orderid)
from orders where orderid > @targetorder)
程序清單2:使用top關鍵字查找目標行
select
top 3
*
from orders
where orderid >=(select max(orderid) from orders
where orderid < @targetorder)
order by
orderid
新聞熱點
疑難解答