Cha*_*per 373 mysql sql database oracle postgresql
我有兴趣学习一些(理想情况下)数据库无关的方法来从数据库表中选择第n行.看看如何使用以下数据库的本机功能实现这一目标也很有趣:
我目前正在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
Run Code Online (Sandbox Code Playgroud)
感谢上述SQL:Firoz Ansari的Weblog
更新:请参阅Troels Arvin关于SQL标准的答案.Troels,您有任何我们能引用的链接吗?
Hen*_*son 330
有很多方法可以在标准的可选部分中执行此操作,但许多数据库都支持自己的方法.
讨论这个和其他事情的一个非常好的网站是http://troels.arvin.dk/db/rdbms/#select-limit.
基本上,PostgreSQL和MySQL支持非标准:
SELECT...
LIMIT y OFFSET x
Run Code Online (Sandbox Code Playgroud)
Oracle,DB2和MSSQL支持标准窗口函数:
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
columns
FROM tablename
) AS foo
WHERE rownumber <= n
Run Code Online (Sandbox Code Playgroud)
(我刚从上面链接的网站复制,因为我从未使用过这些数据库)
更新:从PostgreSQL 8.4开始,支持标准的窗口函数,所以期望第二个例子也适用于PostgreSQL.
更新: SQLite在2018-09-15版本的3.25.0中添加了窗口函数支持,因此这两种形式也适用于SQLite.
Nea*_*all 94
SELECT
*
FROM
mytable
ORDER BY
somefield
LIMIT 1 OFFSET 20;
Run Code Online (Sandbox Code Playgroud)
此示例选择第21行.OFFSET 20告诉Postgres跳过前20条记录.如果您没有指定一个ORDER BY条款,则无法保证您将获得哪条记录,这很少有用.
显然,SQL标准对疯狂窗口函数之外的限制问题保持沉默,这就是每个人以不同方式实现它的原因.
Ell*_*pot 28
我不确定其余的,但我知道SQLite和MySQL没有任何"默认"行排序.在这两种方言中,至少,以下片段从the_table中获取第15个条目,按添加的日期/时间排序:
SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15
Run Code Online (Sandbox Code Playgroud)
(当然,您需要添加一个DATETIME字段,并将其设置为添加条目的日期/时间......)
Ben*_*een 22
SQL 2005及更高版本内置了此功能.使用ROW_NUMBER()函数.它非常适合浏览"上一页和下一页"样式的网页:
句法:
SELECT
*
FROM
(
SELECT
ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
*
FROM
Table_1
) sub
WHERE
RowNum = 23
Run Code Online (Sandbox Code Playgroud)
Tim*_*ers 17
我怀疑这是非常低效的,但这是一个非常简单的方法,它适用于我尝试过的小数据集.
select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc
Run Code Online (Sandbox Code Playgroud)
这将获得第5项,更改第二个顶部数字以获得不同的第n项
仅限SQL服务器(我认为)但应该适用于不支持ROW_NUMBER()的旧版本.
Nic*_*rdi 13
1个小变化:n-1而不是n.
select *
from thetable
limit n-1, 1
Run Code Online (Sandbox Code Playgroud)
Ram*_*ale 12
在SQL Server上验证它:
Select top 10 * From emp
EXCEPT
Select top 9 * From emp
Run Code Online (Sandbox Code Playgroud)
这将给你第10个emp表的行!
Tro*_*vin 11
与某些答案所声称的相反,SQL标准并未对此主题保持沉默.
从SQL:2003开始,您就可以使用"窗口函数"来跳过行并限制结果集.
在SQL:2008中,使用了一种稍微简单的方法
OFFSET skip ROWS
FETCH FIRST n ROWS ONLY
就个人而言,我不认为SQL:2008的添加是真的需要,所以如果我是ISO,我会把它保留在已经相当大的标准之外.
当我们以前在MSSQL 2000中工作时,我们做了所谓的"三重翻转":
EDITED
DECLARE @InnerPageSize int
DECLARE @OuterPageSize int
DECLARE @Count int
SELECT @Count = COUNT(<column>) FROM <TABLE>
SET @InnerPageSize = @PageNum * @PageSize
SET @OuterPageSize = @Count - ((@PageNum - 1) * @PageSize)
IF (@OuterPageSize < 0)
SET @OuterPageSize = 0
ELSE IF (@OuterPageSize > @PageSize)
SET @OuterPageSize = @PageSize
DECLARE @sql NVARCHAR(8000)
SET @sql = 'SELECT * FROM
(
SELECT TOP ' + CAST(@OuterPageSize AS nvarchar(5)) + ' * FROM
(
SELECT TOP ' + CAST(@InnerPageSize AS nvarchar(5)) + ' * FROM <TABLE> ORDER BY <column> ASC
) AS t1 ORDER BY <column> DESC
) AS t2 ORDER BY <column> ASC'
PRINT @sql
EXECUTE sp_executesql @sql
Run Code Online (Sandbox Code Playgroud)
它并不优雅,并不快,但它确实有效.
这里有一个快速解决您困惑的方法。
SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1
Run Code Online (Sandbox Code Playgroud)
这里你可以通过填充N=0得到最后一行,通过N=1填充倒数第二行,通过填充N=3得到倒数第四行等等。
这是面试中非常常见的问题,而且非常简单。
此外,如果您想要金额、ID 或某些数字排序顺序,您可以使用 MySQL 中的 CAST 函数。
SELECT DISTINCT (`amount`)
FROM cart
ORDER BY CAST( `amount` AS SIGNED ) DESC
LIMIT 4 , 1
Run Code Online (Sandbox Code Playgroud)
这里通过填写N = 4,您将能够从CART表中获得最高金额的倒数第五条记录。您可以调整您的字段和表名称并提出解决方案。
SQL SERVER
从顶部选择第n条记录
SELECT * FROM (
SELECT
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE
) AS TMP
WHERE ROW = n
Run Code Online (Sandbox Code Playgroud)
从底部选择第n条记录
SELECT * FROM (
SELECT
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE
) AS TMP
WHERE ROW = n
Run Code Online (Sandbox Code Playgroud)
甲骨文:
select * from (select foo from bar order by foo) where ROWNUM = x
Run Code Online (Sandbox Code Playgroud)
在 Oracle 12c 中,您可以将OFFSET..FETCH..ROWS 选项与ORDER BY
例如,要从顶部获取第三条记录:
SELECT *
FROM sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
718285 次 |
| 最近记录: |