我正在研究的一个相当复杂的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()的子查询,如上所述,这两个都不是我问题的解决方案。
答案 0 :(得分:10)
SQL:2003
定义了窗口函数的概念,其中之一是:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1, col2, col3) AS rn
FROM mytable
) q
WHERE rn = 1
将返回第一条记录。
目前,它由SQL Server
,Oracle
和Jul 01, 2009
支持PostgreSQL 8.4
但请注意,ROW_NUMBER()
中的Oracle
效率低于限制记录的本地方式(即ROWNUM
)。
在我的博客中查看此文章以进行性能比较:
SQL:2008
提供了另一个条款:
SELECT *
FROM mytable
ORDER BY
col1, col2, col3
FETCH FIRST 1 ROW ONLY
,但就目前而言,DB2
仅AFAIK
支持此确切语法。
答案 1 :(得分:8)
如果我理解正确,我认为您正在寻找OVER子句,它允许您对结果集进行分区,并将其定义为ANSI SQL 2003标准的一部分。
在RDBMS平台上实现并非一致。