检索最大/最小记录

时间:2009-07-13 11:57:01

标签: sql theory relational

我正在研究的一个相当复杂的SQL查询让我想到了(ANSI)SQL的限制:

有没有办法检索关于任意排序的最大或最小记录?

换句话说:

给出这样的查询:

SELECT * FROM mytable WHERE <various conditions> ORDER BY <order clause>

是否可以编写一个只返回第一行的查询(可能通过将order子句转换为其他内容)?

我知道你可以使用LIMIT(MySQL)/ ROWNUM(Oracle)或类似的方法来做到这一点,但这不是标准的SQL。

我也知道你可以通过在子查询中获取你感兴趣的最大/最小值(使用MIN()/ MAX())来做到这一点,然后在主SELECT中使用该结果作为标准,即:< / p>

SELECT * FROM mytable WHERE <various conditions> AND myMaxColumn=(
  SELECT MAX(myMaxColumn) FROM mytable WHERE <various conditions>
)

但是只有当我想按单列排序时才有效。我认为没有办法将它推广到多个列(除了嵌套上面的解决方案,但是当用n coluns排序时这意味着2 ^ n个SELECT)。

标准SQL中有一种比嵌套多个子选择更好的方法吗?

Create a SQL query to retrieve most recent records中询问相关问题。但是,那里的答案建议使用LIMIT&amp;朋友,或者使用带有MAX()的子查询,如上所述,这两个都不是我问题的解决方案。

2 个答案:

答案 0 :(得分:10)

SQL:2003定义了窗口函数的概念,其中之一是:

SELECT  *
FROM    (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY col1, col2, col3) AS rn
        FROM    mytable
        ) q
WHERE   rn = 1

将返回第一条记录。

目前,它由SQL ServerOracleJul 01, 2009支持PostgreSQL 8.4

支持

但请注意,ROW_NUMBER()中的Oracle效率低于限制记录的本地方式(即ROWNUM)。

在我的博客中查看此文章以进行性能比较:

SQL:2008提供了另一个条款:

SELECT  *
FROM    mytable
ORDER BY
        col1, col2, col3
FETCH FIRST 1 ROW ONLY

,但就目前而言,DB2AFAIK支持此确切语法。

答案 1 :(得分:8)

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

在RDBMS平台上实现并非一致。