检索最大/最小记录

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)支持这种确切的语法.


Ed *_*per 8

如果我理解正确,我认为您正在寻找OVER子句,它允许您对结果集进行分区,这些结果集是作为ANSI SQL 2003标准的一部分定义的.

它并非在RDBMS平台上一致地实现.