1. 程式人生 > >SQL查詢前幾條資料的方法

SQL查詢前幾條資料的方法

sql在不同資料庫查詢前幾條資料
1. ORACLE
 SELECT * FROM TABLE1 WHERE ROWNUM<=N
 HQL: from table1 t order by t.createTime desc where rownum<=n
2. INFORMIX
 SELECT FIRST N * FROM TABLE1
3. DB2
SELECT * ROW_NUMBER() OVER(ORDER BY COL1 DESC) AS ROWNUM WHERE ROWNUM<=N
或者
SELECT COLUMN FROM TABLE FETCH FIRST N ROWS ONLY

4. SQL SERVER
SELECT TOP N * FROM TABLE1
5. SYBASE
SET ROWCOUNT N
GO
SELECT * FROM TABLE1
6. MYSQL
SELECT * FROM TABLE1 LIMIT N
hibernate查詢記錄的前10條記錄
就像mysql的SQL語句的"select * from table limit 10" hql 不支援limit
query.setFirstResult(0);//從第0條開始取
query.setMaxResults(10);//取十條記錄
7. FOXPRO
SELECT * TOP N FROM TABLE ORDER BY COLUMN

8.postgres查詢前幾條記錄SQL
SELECT * FROM TABLE LIMIT
跟我學SQL分為三部分,其中涵蓋了有關SQL標準的基本知識。在上一篇文章裡我們討論了一些資料庫術語和4種最基本的資料查詢型別。此外,我們還解釋了WHERE子句和條件語句的用法,同時我們提供了各類查詢的具體示例。
在這篇文章裡,我們將就其他一些SQL函式和子句進行闡述,供你用於基本的SELECT資料查詢中。
SELECT選項精製結果
正如我們從上一篇文章中所讀到的那樣,SELECT語句具有種類繁多的各類選項,這些選項可以用來控制資料返回的方式。這些選項以子句、關鍵詞和函式的形式存在。
子句是一種修改結果的語句。子句不是必要的語句但它對資料的內容及其顯示進行了提煉。WHERE子句就是這樣的子句。

關鍵詞觸發資料庫的內在功能。這些關鍵詞在有時甚至是查詢所必需的。例如“INSERT INTO table_name (column1) VALUES (‘data1’);”語句中的INTO和VALUE就是如此。我們將瞭解DISTINCT關鍵詞,它能觸發一些非常有用的可選功能。
下面總結了一些最常用的子句、關鍵詞和函式。然後我會對每一部分舉例說明。
·ORDER BY – 按照指定列排序返回結果的子句
·DISTINCT – 只返回結果集合內唯一行的關鍵詞
·COUNT -- 返回匹配查詢的資料行總數數值的函式
·AVG – 該函式返回指定列的平均值
·SUM –該函式把指定的列中的數字加起來
·MIN – 該函式返回列中最小的非NULL值
·MAX –該函式返回列中的最大值
·GROUP BY – 按列彙集查詢函式結果的子句
用ORDER BY對查詢結果排序
ORDER BY子句讓資料庫對查詢結果排序,這樣你就無須自己編寫應用程式進行“手工”排序了。ORDER BY子句必須放在查詢語句的結尾。其基本用法如下:
SELECT * FROM Contacts ORDER BY first_name;
你可以隨意在任何選擇語句中使用ORDER BY 子句返回多列結果。你還可以用它連線其他子句:
SELECT first_name, last_name FROM Contacts WHERE first_name BETWEEN ‘a’ AND ‘k’ ORDER BY last_name;
你可以對多列資料排序。優先順序按從左到右依次降低,所以查詢語句中各列的排列順序很重要。
SELECT * FROM Contacts ORDER BY company, last_name, first_name;
查詢結果預設按數字或者字母的升序排序。你可以在ORDER BY 子句後面加上DESC關鍵詞改成降序排列。在下面的例子中,最高的net_amount排在最先(降序)。假如兩行或者兩行以上資料都包含了同樣的net_amount值,那麼同行中last_name值在字母表中最先出現的排先,因為last_name一列還是按照升序排序的。
SELECT * FROM Sales ORDER BY net_amount DESC, last_name, first_name;
在按照定義的列名排序以後,大多數資料庫隨後將按照資料表內的第一列排序然後順序向右再排序。具體的實現各有變化,因此,如果排序在應用中比較重要那麼你應該明確地定義所要排序的列。
另外一值得注意的問題是,採用ORDER BY子句(以及WHERE子句),你正在用來排序結果的資料列並不一定得是返回結果集合的一部分。只要所有引用的列都在資料表記憶體在則下例完全有效:
SELECT company, first_name, net_amount FROM Sales ORDER BY start_date, last_name;
DISTINCT返回不重複結果
DISTINCT關鍵詞只返回結果集合內不重複的資料行。例如,有時你可能需要找出Sales表內的公司,但是你又不想看見每個條目。於是你可以用DISTINCT對應每一公司名返回一行資料:
SELECT DISTINCT company FROM Sales;
在使用DISTINCT時,它適用於所有的請求列。如果你打算列出表內的所有銷售人員和他們所代表的公司而非每一銷售記錄,那麼你可以使用下列語句。注意,這樣操作還可能返回同一公司的若干條目等等。
SELECT DISTINCT company, last_name, first_name FROM Sales;
你 還可以在對結果縮小範圍和進行排序時結合SELECT語句使用DISTINCT。為了確定顯示的內容,資料庫首先會證實精練的請求是否匹配資料行,然後應 用DISTINCT功能。在全部結果集合都得以確定之後即處理ORDER BY子句。如下例所示,只有net_amount大於100的資料行才被返回。由於DISTINCT保留遇見的第1個匹配查詢條件的資料行而丟棄其他匹配 行,所以ORDER BY語句所引用的net_amount看起來就好象產生了隨機的結果。
SELECT DISTINCT company, last_name, first_name FROM Sales WHERE net_amount > 100 ORDER BY company, net_amount;
函式應用邏輯
返回單一值的函式稱做聚集函式(aggregate function)。通過應用程式訪問下列聚集函式的結果時,包含結果的“欄位名”就是你所使用的實際函式。例如,在分析你的資料庫結果時,結果陣列的鍵值可能如下所示:
$keyname = “COUNT(*)”;
$resultkey = “AVG(net_amount)”;
COUNT
COUNT函式計算出結果集合中的資料行數。和其他函式一樣它接受一個引數。以下的基本示例能告訴你資料表內的行數:SELECT COUNT(*) FROM Sales;
你也可以用它來計算任何結果集合中的行數。
SELECT COUNT(*) FROM Sales WHERE net_amount > 100;
如果你想看看某特定列有多少行包含非空值,那你不妨對該列使用COUNT函式。注意,除非資料庫設定為欄位為空時預設填充NULL否則將返回表內資料行的總數。另外,列出的列在超出一個的情況下會引起錯誤。
SELECT COUNT(company) FROM Sales;
COUNT還可以用來計算DISTINCT結果集合中的行數。
SELECT COUNT(DISTINCT company, last_name) FROM Sales;
COUNT語句通常用在程式中確定FOR迴圈的迴圈次數。
AVG
AVG返回某列所有欄位的平均值,該列必須是數字資料型別。該函式用列的名字作為其引數,如果列欄位資料型別是非數字型別的則函式返回“0”。SELECT AVG(net_amount) FROM Sales;
你可以結合子句限制該函式的應用範圍。
SELECT AVG(net_amount) FROM Sales WHERE company LIKE ‘�CD Co%’;
就象所有聚集函式一樣,ORDER BY語句將被忽略。
SUM
SUM的工作方式和AVG差不多,只不過該函式返回結果集合中所有欄位值的和。
SELECT SUM(net_amount) FROM Sales WHERE net_amount > 100;
AVG、SUM、MIN和MAX函式在沒有指定列的情況下都會返回錯誤,所以你不能使用“*”萬用字元。
MIN
MIN返回指定列中最小的非空值。如果指定列是數字資料型別則結果將是最小的數字。如果它是一種字串資料型別則函式將返回按字母表順序出現的第1個值。SELECT MIN(net_amount) FROM Sales WHERE last_name = “Smith”;
SELECT MIN(last_name) FROM Sales;
MAX
MAX的工作方式和MIN函式一樣,只不過該函式返回最大的非空值。該函式也可以用於字串或者數字列
SELECT MAX(net_amount) FROM Sales;
SELECT MAX(company) FROM Sales WHERE net_amount > 100;
MAX函式有時還用在包含自動遞增鍵欄位的列上確定下一條目的鍵ID。除非你正在執行一個非公開的資料庫,否則在使用這一資訊插入下一條目時務必謹慎,以防其他使用者先你執行資料操作。
GROUP BY 令函式更有用
雖然以上提到的所有這些函式都能提供相當有用的資訊,但是,如果有GROUP BY子句幫忙的話更能讓你在列的欄位子集中應用這些函式。不要對你的Sales表中每一家公司一次又一次地執行MAX函式查詢——你完全可以帶GROUP BY子句獲得同樣的結果:
SELECT company, MAX(net_amount) FROM Sales GROUP BY company;
這樣做可以獲得每家公司net_amount的的最大值。在選擇多列名的時候也可以採用該語句,你還可以用多列來對函式結果分組。
下面的例子演示了以上各種方式。首先,包括GROUP BY子句可以令你指定要顯示的其他列。然而,你得知道這個例子將返回在組中遇到的第1個last_name值;Sum( net_amount )將顯示全部公司的結果而不僅僅針對匹配姓氏的資料行。這是因為,我們只使用了Company欄位來定義我們的組。
SELECT company, last_name, SUM(net_amount) FROM Sales GROUP BY company;
在上面的例子中,last_name列實際上並沒有提供什麼有用的資訊,但這樣做是為了在下一個例子中要用到的功能做準備。你可以建立多列定義的組。這樣就可以在結果集合中產生針對特定行的函式結果,而結果集合則是由所有指定的GROUP BY列聯合起來建立的:
SELECT company, AVG(net_amount), last_name FROM Sales GROUP BY company, last_name;
上面的例子給每家公司中每一姓氏給出了平均的net_amount。你列出GROUP BY列的順序控制著結果的排序,但是實際的函式值結果是一樣的。
下面的例子表明如何組織結果而不顯示分組的列。在有些場合這樣做是很有用的,例如,如果要顯示個人的銷售量但卻不顯示姓名就能用上下面的例子了:
SELECT company, COUNT(sale_id) FROM Sales GROUP BY company, last_name;
限制使用GROUP BY的查詢
如你在以上示例中所看到的那樣,你可以結合WHERE字句利用以上的概念限制查詢的範圍。WHERE子句會首先被計算,然後執行函式。在使用組的時候就是這樣的。
SELECT company, AVG(net_amount), FROM Sales WHERE net_amount > 100 GROUP BY company;
上面的例子只對那些滿足WHERE限制條件的資料行適用AVG函式。注意,WHERE子句必須放在GROUP BY子句之前。你還可以用HAVING語句對分組計算之後限制返回的結果集合。
SELECT company, AVG(net_amount), FROM Sales WHERE last_name BETWEEN ‘a’ AND ‘m’ GROUP BY company HAVING AVG(net_amount) > 500;

上面的語句計算每家公司net_amount的平均值,而且只計算那些姓氏滿足限制條件的銷售人員的銷售量,同時只顯示大於500的結果。
MySQL可以很好的支援大資料量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在建立表的時候,為了獲得更好的效能, 我們可以將表中欄位的寬度設得儘可能小。例如,在定義郵政編碼這個欄位時,如果將其設定為CHAR(255),顯然給資料庫增加了不必要的空間,甚至使用 VARCHAR這種型別也是多餘的,因為CHAR(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用 MEDIUMINT而不是BIGIN來定義整型欄位。
另外一個提高效率的方法是在可能的情況下,應該儘量把欄位設定為NOT NULL,這樣在將來執行查詢的時候,資料庫不用去比較NULL值。
對於某些文字欄位,例如“省份”或者“性別”,我們可以將它們定義為ENUM型別。因為在MySQL中,ENUM型別被當作數值型資料來處理,而數值型資料被處理起來的速度要比文字型別快得多。這樣,我們又可以提高資料庫的效能。
2、使用連線(JOIN)來代替子查詢(Sub-Queries)
MySQL從4.1開始支援SQL的子查詢。這個技術可以使用SELECT語句來建立一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢 中。例如,我們要將客戶基本資訊表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售資訊表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查 詢,如下所示:
DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )
使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死,並且寫起來也很容易。但是,有些情況下,子查 詢可以被更有效率的連線(JOIN).. 替代。例如,假設我們要將所有沒有訂單記錄的使用者取出來,可以用下面這個查詢完成:
SELECT * FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )
如果使用連線(JOIN).. 來完成這個查詢工作,速度將會快很多。尤其是當salesinfo表中對CustomerID建有索引的話,效能將會更好,查詢如下:
SELECT * FROM customerinfo LEFT JOIN salesinfoON customerinfo.CustomerID=salesinfo. CustomerID WHERE salesinfo.CustomerID IS NULL
連線(JOIN).. 之所以更有效率一些,是因為 MySQL不需要在記憶體中建立臨時表來完成這個邏輯上的需要兩個步驟的查詢工作。
3、使用聯合(UNION)來代替手動建立的臨時表
MySQL 從 4.0 的版本開始支援 UNION 查詢,它可以把需要使用臨時表的兩條或更多的 SELECT 查詢合併的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。使用 UNION 來建立查詢的時候,我們只需要用 UNION作為關鍵字把多個 SELECT 語句連線起來就可以了,要注意的是所有 SELECT 語句中的欄位數目要想同。下面的例子就演示了一個使用 UNION的查詢。
SELECT Name, Phone FROM client UNION SELECT Name, BirthDate FROM author
UNION
SELECT Name, Supplier FROM product
4、事務
儘管我們可以使用子查詢(Sub-Queries)、連線(JOIN)和聯合(UNION)來建立各種各樣的查詢,但不是所有的資料庫操作都可以只用一 條或少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。但是在這種情況下,當這個語句塊中的某一條語句執行出錯的時候, 整個語句塊的操作就會變得不確定起來。設想一下,要把某個資料同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意 外狀況,造成第二個表中的操作沒有完成,這樣,就會造成資料的不完整,甚至會破壞資料庫中的資料。要避免這種情況,就應該使用事務,它的作用是:要麼語句 塊中每條語句都操作成功,要麼都失敗。換句話說,就是可以保持資料庫中資料的一致性和完整性。事物以BEGIN 關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那麼,ROLLBACK命令就可以把資料庫恢復到BEGIN開始之前的狀態。
BEGIN;
INSERT INTO salesinfo SET CustomerID=14;
UPDATE inventory SET Quantity=11
WHERE item='book';
COMMIT;
事務的另一個重要作用是當多個使用者同時使用相同的資料來源時,它可以利用鎖定資料庫的方法來為使用者提供一種安全的訪問方式,這樣可以保證使用者的操作不被其它的使用者所幹擾。
5、鎖定表
儘管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨佔性,有時會影響資料庫的效能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的使用者請求只能暫時等待直到該事務結束。如果一個數據庫系統只有少數幾個使用者
來使用,事務造成的影響不會成為一個太大的問題;但假設有成千上萬的使用者同時訪問一個數據庫系統,例如訪問一個電子商務網站,就會產生比較嚴重的響應延遲。
其實,有些情況下我們可以通過鎖定表的方法來獲得更好的效能。下面的例子就用鎖定表的方法來完成前面一個例子中事務的功能。
LOCK TABLE inventory WRITE
SELECT Quantity FROM inventory
WHEREItem='book';
...
UPDATE inventory SET Quantity=11
WHEREItem='book';
UNLOCK TABLES
這裡,我們用一個 SELECT 語句取出初始資料,通過一些計算,用 UPDATE 語句將新值更新到表中。包含有 WRITE 關鍵字的 LOCK TABLE 語句可以保證在 UNLOCK TABLES 命令被執行之前,不會有其它的訪問來對 inventory 進行插入、更新或者刪除的操作。
6、使用外來鍵
鎖定表的方法可以維護資料的完整性,但是它卻不能保證資料的關聯性。這個時候我們就可以使用外來鍵。例如,外來鍵可以保證每一條銷售記錄都指向某一個存在的 客戶。在這裡,外來鍵可以把customerinfo 表中的CustomerID對映到salesinfo表中CustomerID,任何一條沒有合法CustomerID的記錄都不會被更新或插入到 salesinfo中。
CREATE TABLE customerinfo
(
CustomerID INT NOT NULL ,
PRIMARY KEY ( CustomerID )
) TYPE = INNODB;
CREATE TABLE salesinfo
(
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY(CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo
(CustomerID) ON DELETECASCADE
) TYPE = INNODB;
注意例子中的引數“ON DELETE CASCADE”。該引數保證當 customerinfo 表中的一條客戶記錄被刪除的時候,salesinfo 表中所有與該客戶相關的記錄也會被自動刪除。如果要在 MySQL 中使用外來鍵,一定要記住在建立表的時候將表的型別定義為事務安全表 InnoDB型別。該型別不是 MySQL 表的預設型別。定義的方法是在 CREATE TABLE 語句中加上 TYPE=INNODB。如例中所示。
Mysql Limit操作
select * from table LIMIT 5,10; #返回第6-15行資料
select * from table LIMIT 5; #返回前5行
select * from table LIMIT 0,5; #返回前5行
效能優化:
基於MySQL5.0中limit的高效能,我對資料分頁也重新有了新的認識.
1.
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
Select ID From cyclopedia Order By ID limit 90001
) As tmp
) limit 100;
2.
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
Select ID From cyclopedia Order By ID limit 90000,1
) As tmp
) limit 100;
同樣是取90000條後100條記錄,第1句快還是第2句快?
第1句是先取了前90001條記錄,取其中最大一個ID值作為起始標識,然後利用它可以快速定位下100條記錄
第2句擇是僅僅取90000條記錄後1條,然後取ID值作起始標識定位下100條記錄
第1句執行結果.100 rows in set (0.23) sec
第2句執行結果.100 rows in set (0.19) sec
很明顯第2句勝出.看來limit好像並不完全像我之前想象的那樣做全表掃描返回limit offset+length條記錄,這樣看來limit比起MS-SQL的Top效能還是要提高不少的.
其實第2句完全可以簡化成
Select * From cyclopedia Where ID>=(
Select ID From cyclopedia limit 90000,1
)limit 100;
直接利用第90000條記錄的ID,不用經過Max運算,這樣做理論上效率因該高一些,但在實際使用中幾乎看不到效果,因為本身定位ID返回的就是1條記錄,Max幾乎不用運作就能得到結果,但這樣寫更清淅明朗,省去了畫蛇那一足.
可是,既然MySQL有limit可以直接控制取出記錄的位置,為什麼不乾脆用Select * From cyclopedia limit 90000,1呢?豈不更簡潔?
這樣想就錯了,試了就知道,結果是:1 row in set (8.88) sec,怎麼樣,夠嚇人的吧,讓我想起了昨天在4.1中比這還有過之的"高分".Select * 最好不要隨便用,要本