sle*_*ske 4 sql theory relational
我正在研究的一个相当复杂的SQL查询让我思考(ANSI)SQL的局限性:
有没有办法检索关于任意排序的最大或最小记录?
换一种说法:
给出这样的查询:
SELECT * FROM mytable WHERE <various conditions> ORDER BY <order clause>
Run Code Online (Sandbox Code Playgroud)
是否可以编写一个只返回第一行的查询(可能通过将order子句转换为其他内容)?
我知道你可以使用LIMIT(MySQL)/ ROWNUM(Oracle)或类似的方法来做到这一点,但这不是标准的SQL.
我也知道你可以通过在子查询中获取你感兴趣的最大/最小值(使用MIN()/ MAX())来做到这一点,然后在主SELECT中使用该结果作为标准,即:
SELECT * FROM mytable WHERE <various conditions> AND myMaxColumn=(
SELECT MAX(myMaxColumn) FROM mytable WHERE <various conditions>
)
Run Code Online (Sandbox Code Playgroud)
但这只有在我想按单列排序时才有效.我认为没有办法将它推广到多个列(除了嵌套上面的解决方案,但这意味着当用n coluns排序时有2 ^ n个SELECT).
那么标准SQL中有一种比嵌套多个子选择更好的方法吗?
在创建SQL查询中询问相关问题以检索最近的记录.但是,那里的答案建议使用LIMIT和朋友,或使用带有MAX()的子查询,如上所述,这两个都不是我的问题的解决方案.
Qua*_*noi 10
SQL:2003 定义窗口函数的概念,其中之一:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1, col2, col3) AS rn
FROM mytable
) q
WHERE rn = 1
Run Code Online (Sandbox Code Playgroud)
将返回第一条记录.
至于现在,它是由支持SQL Server,Oracle并且由于Jul 01, 2009通过PostgreSQL 8.4
但请注意,ROW_NUMBER()in Oracle的效率低于限制记录的本地方式(即ROWNUM).
在我的博客中查看此文章以进行性能比较:
SQL:2008 提供另一个条款来做到这一点:
SELECT *
FROM mytable
ORDER BY
col1, col2, col3
FETCH FIRST 1 ROW ONLY
Run Code Online (Sandbox Code Playgroud)
,但就目前而言,DB2只有(AFAIK)支持这种确切的语法.