當我處理Zend Framework's database component時,我們試圖抽象出MySQL,PostgreSQL和SQLite支持的LIMIT
子句的功能。也就是說,創建一個查詢可以做到這樣:在Microsoft SQL Server 2000中模擬MySQL LIMIT子句
$select = $db->select();
$select->from('mytable');
$select->order('somecolumn');
$select->limit(10, 20);
當數據庫支持LIMIT
,這將產生類似下面的SQL查詢:對品牌的數據庫
SELECT * FROM mytable ORDER BY somecolumn LIMIT 10, 20
這是更爲複雜,不支持LIMIT
(順便說一下,該子句不是標準SQL語言的一部分)。如果可以生成行號,則將整個查詢設爲派生表,並在外部查詢中使用BETWEEN
。這是Oracle和IBM DB2的解決方案。微軟SQL Server 2005中也有類似的行數的功能,所以可以這樣寫查詢:
SELECT z2.*
FROM (
SELECT ROW_NUMBER OVER(ORDER BY id) AS zend_db_rownum, z1.*
FROM (...original SQL query...) z1
) z2
WHERE z2.zend_db_rownum BETWEEN @offset+1 AND @[email protected];
但是,Microsoft SQL Server 2000不具備ROW_NUMBER()
功能。
所以我的問題是,你能想出一種方法來模仿Microsoft SQL Server 2000中的LIMIT
功能,僅使用SQL?不使用遊標或T-SQL或存儲過程。它必須支持LIMIT
這兩個參數,包括計數和偏移量。使用臨時表的解決方案也是不可接受的。
編輯:
的MS SQL Server 2000中最常見的解決方案似乎是類似下面,例如通過75獲得行50:
SELECT TOP 25 *
FROM (
SELECT TOP 75 *
FROM table
ORDER BY BY field ASC
) a
ORDER BY field DESC;
然而,這並未」如果總的結果集是60行,則工作。內部查詢返回60行,因爲它位於前75位。然後,外部查詢返回行35-60,這不符合50-75所需的「頁面」。基本上,這個解決方案的工作原理除非你需要結果集的最後一個「頁面」,這個頁面並不是頁面大小的倍數。
編輯:
另一種解決方案更好地工作,但只有當你能承擔的結果集包括一列,它是獨一無二的:
SELECT TOP n *
FROM tablename
WHERE key NOT IN (
SELECT TOP x key
FROM tablename
ORDER BY key
);
結論:
不一般目的解決方案似乎存在用於在MS SQL Server 2000中模擬LIMIT
。如果您可以使用ROW_NUMBER()
函數,存在一個很好的解決方案離子在MS SQL Server 2005.
是的,這是接近的,但它只有在用戶在臨時查詢結果的唯一關鍵工作。你如何在GROUP BY查詢或連接多個表的查詢中執行此操作? – 2009-04-06 17:55:41