天天看點

關于sql語句查詢--top關鍵字

Top關鍵字:

1、首先引用一位網友出錯的例子,sql="select top 30 * from data where title='"&title1&"' order by id desc"

分析出錯原因:sql語句裡同時存在 where 和 top 語句的時候,并且where條件列不是合适的索引,程式執行的是全表掃描,首先是查找符合where條件的記錄,而這裡的top限制形同虛設。如果全表是百萬級别以上的資料表,那麼就這麼一個簡單的判斷,就有可能拖垮資料庫。

2、解決辦法就是去掉where條件篩選語句,如果你希望使用selcet top語句,并且還要附帶where條件,那麼條件中的列就得是合适的索引, 如聚集索引、複合索引裡的主列 等,同時,where條件裡也要盡量避開使用函數,or,判斷NULL等會引起全部掃描的語句。這一點要記住,不然執行的是全表掃描。

3、如何選出第N條到第2N條記錄呢。這樣的sql語句就可以了:

“select top n * from TABLE_NAME where id not in (select top n id from TABLE_NAME order by id desc)"

4、對Top基本了解下(TOP 和 SET ROWCOUNT)

SELECT 語句中的TOP子句限制單個查詢傳回的行數,而SET ROWCOUNT限制所有後續查詢影響的行數。在很多程式設計任務中這些指令提供了高效率。

SET ROWCOUNT在SELECT,INSERT,UPDATE OR DELETE語句中設定可以被影響的最大行數。這些設定在指令執行時馬上生效并且隻影響目前的會話。為了移除這個限制執行SET ROWCOUNT 0。一些實際的任務用TOP or SET ROWCOUNT比用标準的SQL指令對程式設計是更有效率的。讓我們在幾個例子中證明:

在幾乎所有的資料庫中最流行的一個查詢是請求一個清單中的前N項。在 pubs資料庫案例中,我們可以查找銷售最好CD的前五項。比較用TOP,SET ROWCOUNT和使用ANSI SQL的三種方案。

(1)Select title,ytd_salesFrom titlesa Where (select count(*)From titlesb  Where b.ytd_sales>a.ytd_sales)<5 Order by ytd_sales DESC

這個純ANSI SQL方案執行一個效率可能很低的關聯子查詢,特别的在這個例子中,在ytd_sales上沒有索引支援。另外,這個純的标準SQL指令沒有過濾掉在ytd_sales的空值,也沒有差別多個CD間有關聯的情況。

(2)SET ROWCOUNT 5 SELECT title, ytd_salesFROM titlesORDER BY ytd_sales DESCSET ROWCOUNT 0

(3)SELECT TOP 5 title, ytd_salesFROM titlesORDER BY ytd_sales DESC

第二個方案使用SET ROWCOUNT來停止SELECT查詢,而第三個方案是當它找到前五行時用TOP n來停止。在這種情況下,在獲得結果之前我們也要有一個ORDER BY子句強制對整個表進行排序。兩個查詢的查詢計劃實際上是一樣的。然而,TOP優于SET ROWCOUNT的關鍵點是SET必須處理ORDER BY子句所需的工作表,而TOP 不用。

總結:在一個大表上,我們可以為表上建立一個索引以避免排序,查詢将使用該索引找到前5行并停止。

ROWNUM僞列:

1、使用SELECT語句傳回的結果集,希望按特定條件查詢前N條記錄,可以使用僞列ROWNUM。ROWNUM是對結果集加一個僞列,先查到結果集後再加上一個列,是符合條件結果的序列号;從1開始排起,隻能用< > = !=這些比較符合。

ROWNUM對于等于某值的查詢條件,比如查詢第一條記錄,可以使用ROWNUM=1作為條件;但是如果查詢第二條記錄寫ROWNUM=2則查詢不到資料,ROWNUM的=判斷隻對于1有效;

2、同理,查詢大于某值的查詢條件,ROWNUM>n(n>1的自然數)這種條件不成立;那如何查詢第一行以後的記錄呢?

solution:用子查詢解決,但是必須為rownum設定别名,"select * from (select rownum no ,id,name from table1) where  no >1";

3、ROWNUM對于小于某值的查詢是可以的,select * from table1 where rownum<3

4、ROWNUM和排序

Oracle中rownum是在取資料時産生的序号,想對指定排序的資料指定rownum行資料就要做處理了:

"select rownum,id,name from table1 order by name",查詢結果按name排序,但是rownum不是按1、2、3...排列,而是按記錄插入時的順序給記錄排号;

solution:使用子查詢,select rownum ,id,name from(select * from table1 order by name)