server比較 - sqlite mysql postgresql比較




如何選擇SQL數據庫表中的第n行? (19)

我有興趣學習從數據庫表中選擇第n行的一些(理想情況下)數據庫不可知的方式。 使用以下數據庫的本地功能可以實現這一點也很有趣:

  • SQL Server
  • MySQL的
  • PostgreSQL的
  • SQLite的
  • 神諭

我目前在SQL Server 2005中做類似下面的事情,但我很想看到其他更多不可知的方法:

WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000

對上述SQL 感興趣Firoz Ansari的博客

更新:請參閱Troels Arvin關於SQL標準的答案Troels,你有沒有我們可以引用的鏈接?


SQL SERVER

從頂部選擇第n個記錄

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

從底部選擇第n個記錄

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

1小改變:n-1而不是n。

select *
from thetable
limit n-1, 1

SQL 2005及更高版本內置此功能。 使用ROW_NUMBER()函數。 對於具有<<上一個和下一個>>樣式瀏覽的網頁,這是非常好的:

句法:

SELECT
    *
FROM
    (
        SELECT
            ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
            *
        FROM
            Table_1
    ) sub
WHERE
    RowNum = 23

T-SQL - 從表中選擇第N個RecordNumber

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from TableName) T where T.Rno = RecordNumber

Where  RecordNumber --> Record Number to Select
       TableName --> To be Replaced with your Table Name

例如,要從表Employee選擇第5條記錄,您的查詢應該是

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from Employee) T where T.Rno = 5

令人難以置信的是,你可以找到一個SQL引擎執行這個...

WITH sentence AS
(SELECT 
    stuff,
    row = ROW_NUMBER() OVER (ORDER BY Id)
FROM 
    SentenceType
    )
SELECT
    sen.stuff
FROM sentence sen
WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1

但是,真的,這並不是所有這些只是為了優秀的數據庫設計而放在首位? 有幾次我需要這樣的功能,這是一個簡單的查詢來做出快速報告的功能。 對於任何真實的工作,使用這樣的技巧都會招致麻煩。 如果需要選擇一個特定的行,那麼只需要一個具有連續值的列並且可以完成。


加:

LIMIT n,1

這會將結果限制為從結果n開始的一個結果。


在Oracle 12c中,您可以使用ORDER BY OFFSET..FETCH..ROWS選項

例如,要從頂部獲得第3條記錄:

SELECT * 
FROM   sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;

在Sybase SQL Anywhere中:

SELECT TOP 1 START AT n * from table ORDER BY whatever

不要忘記ORDER BY或者它沒有意義。


在我看來,為了高效率,您需要1)生成0到1之間的隨機數,小於數據庫記錄的數量,以及2)能夠選擇該位置處的行。 不幸的是,不同的數據庫有不同的隨機數生成器和不同的方式來選擇結果集中某個位置的行 - 通常您需要指定要跳過的行數以及需要的行數,但對於不同的數據庫,其做法各不相同。 這裡有一些適合我的SQLite:

select * 
from Table 
limit abs(random()) % (select count(*) from Words), 1;

它的確依賴於能夠在limit子句中使用子查詢(在SQLite中,它是LIMIT <recs to skip>,recs to take>)選擇表中記錄的數量應該特別有效,它是數據庫的一部分元數據,但這取決於數據庫的實現。 另外,我不知道查詢是否會在檢索第N條記錄之前實際構建結果集,但我希望它不需要。 請注意,我沒有指定“order by”子句。 “按順序”之類的東西可能會更好 - 如果主鍵有索引 - 從索引中獲取第N條記錄的速度可能會更快,如果數據庫無法從數據庫本身獲取第N條記錄而不構建結果集。


對於SQL Server來說,按行號進行操作的通用方法就是這樣:SET ROWCOUNT @row - @ row =您想要處理的行號。

例如:

設置rowcount 20 - 將行設置為第20行

從dbo.sandwich選擇肉類,奶酪 - 從第20排的餐桌上選擇列

設置rowcount 0 - 將rowcount設置回所有行

這將返回第20行的信息。 請務必在之後放入行數0。

我知道noobish,但我是一個SQL noob,我已經使用它,所以我能說什麼?


我不知道其餘的,但我知道SQLite和MySQL沒有任何“默認”行排序。 在這兩種方言中,至少,下面的代碼片段從thetable中抓取第15個條目,按添加的日期/時間排序:

SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15

(當然,您需要添加一個DATETIME字段,並將其設置為添加條目的日期/時間...)


沒有什麼特別的功能,如果你像我一樣使用Caché的話......

SELECT TOP 1 * FROM (
  SELECT TOP n * FROM <table>
  ORDER BY ID Desc
)
ORDER BY ID ASC

鑑於您擁有可以信任的ID列或日期戳列。


甲骨文:

select * from (select foo from bar order by foo) where ROWNUM = x

與某些答案聲稱相反,SQL標準並沒有對此問題保持沉默。

由於SQL:2003,您可以使用“窗口函數”來跳過行並限制結果集。

在SQL:2008中,使用了一個稍微簡單的方法
OFFSET skip ROWS FETCH FIRST n ROWS ONLY

就我個人而言,我認為SQL:2008的增加並不是真的需要,所以如果我是ISO,我會把它放在已經相當大的標準中。


這是您混亂的快速解決方案。

SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1

在這裡你可以通過填充N = 0,第二個最後N = 1,第四個最後一個填充N = 3等等來獲得最後一行。

這是面試中很常見的問題,這是非常簡單的答案。

進一步如果你想要的金額,ID或一些數字排序順序可能會去CAST函數在MySQL中。

SELECT DISTINCT (`amount`) FROM cart ORDER BY CAST( `amount` AS SIGNED ) DESC LIMIT 4 , 1

在這里通過填充N = 4您將能夠從CART表中獲得最高金額的第五最後記錄。 你可以適合你的領域和表名,並提出解決方案。


這是我最近為Oracle寫的一個通用版本,它允許進行動態分頁/排序 - HTH

-- p_LowerBound = first row # in the returned set; if second page of 10 rows,
--                this would be 11 (-1 for unbounded/not set)
-- p_UpperBound = last row # in the returned set; if second page of 10 rows,
--                this would be 20 (-1 for unbounded/not set)

OPEN o_Cursor FOR
SELECT * FROM (
SELECT
    Column1,
    Column2
    rownum AS rn
FROM
(
    SELECT
        tbl.Column1,
        tbl.column2
    FROM MyTable tbl
    WHERE
        tbl.Column1 = p_PKParam OR
        tbl.Column1 = -1
    ORDER BY
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 1, Column1, 'X'),'X'),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 1, Column1, 'X'),'X') DESC,
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate) DESC
))
WHERE
    (rn >= p_lowerBound OR p_lowerBound = -1) AND
    (rn <= p_upperBound OR p_upperBound = -1);

SELECT
    top 1 *
FROM
    table_name
WHERE
    column_name IN (
        SELECT
            top N column_name
        FROM
            TABLE
        ORDER BY
            column_name
    )
ORDER BY
    column_name DESC

我寫了這個查詢來找到第N行。 這個查詢的例子是

SELECT
    top 1 *
FROM
    Employee
WHERE
    emp_id IN (
        SELECT
            top 7 emp_id
        FROM
            Employee
        ORDER BY
            emp_id
    )
ORDER BY
    emp_id DESC

select * from 
(select * from ordered order by order_id limit 100) x order by 
x.order_id desc limit 1;

首先按升序排序選擇前100行,然後按降序排列選擇最後一行,並將其限制為1.但是,由於它訪問數據兩次,因此這是一個非常昂貴的陳述。





postgresql