记录中最大日期的提取

37

假设我提取了一些数据。

例如:

SELECT A, date
FROM table

我只想获取每个A值下日期最大的记录。我可以这样写:

SELECT A, col_date
  FROM TABLENAME t_ext
 WHERE col_date = (SELECT MAX (col_date)
                     FROM TABLENAME t_in
                    WHERE t_in.A = t_ext.A)

但我的查询语句非常长... 是否有更紧凑的方法使用分析函数来实现相同的功能?

7个回答

75

分析函数方法的实现大致如下:

SELECT a, some_date_column
  FROM (SELECT a,
               some_date_column,
               rank() over (partition by a order by some_date_column desc) rnk
          FROM tablename)
 WHERE rnk = 1

请注意,根据您想如何处理并列(或者您的数据模型是否可能存在并列),您可能需要使用 ROW_NUMBERDENSE_RANK 分析函数而不是 RANK


5
如果在TABLENAME中有两行具有相同的A值和相同的SOME_DATE_COLUMN值,则会发生绑定。您的原始查询将返回这两行,我的查询也将返回这两行。另一方面,如果您使用ROW_NUMBER函数,则只会返回其中一行(尽管选择返回哪一行是任意的)。 - Justin Cave

24
如果datecol_date是相同的列,你应该简单地执行以下操作:
SELECT A, MAX(date) FROM t GROUP BY A

为什么不使用:

WITH x AS ( SELECT A, MAX(col_date) m FROM TABLENAME GROUP BY A )
SELECT t.A, t.date FROM TABLENAME t JOIN x ON x.A = t.A AND x.m = t.col_date

否则:
SELECT A, FIRST_VALUE(date) KEEP(dense_rank FIRST ORDER BY col_date DESC)
  FROM TABLENAME
 GROUP BY A

5
@Matt:是的,但仅当OP只想要这两列而不是整行(正如问题所暗示的那样)。 - ypercubeᵀᴹ
1
@ypercube 我同意,这就是问题的样子。 - Matt Donnan
1
我无法让我的 Oracle 11g 中的第三个查询工作。第二个查询缺少一个 group by 子句。应该是:WITH x AS (SELECT A, MAX(col_date) m FROM TABLENAME **group by A**) SELECT A, date FROM TABLENAME t JOIN x ON x.A = t.A AND x.m = t.col_date - EAmez

10
您也可以使用以下方法:
SELECT t.*
  FROM 
        TABLENAME t
    JOIN
        ( SELECT A, MAX(col_date) AS col_date
          FROM TABLENAME
          GROUP BY A
        ) m
      ON  m.A = t.A
      AND m.col_date = t.col_date

1
如果在(a,col_date)上有索引,尤其是对于每个不同的A值有大量日期的情况下,这将是一个不错的选择。 - APC

4

A 是关键字,max(date) 是值,我们可以将查询简化如下:

SELECT distinct A, max(date) over (partition by A)
  FROM TABLENAME

2

Justin Cave的回答是最好的,但如果你想尝试另一个选项,请尝试这个:

select A,col_date
from (select A,col_date
    from tablename 
      order by col_date desc)
      where rownum<2

2
自从Oracle 12C以来,您可以使用FETCH FIRST ROW ONLY获取特定数量的行。 在您的情况下,这意味着需要ORDER BY,因此性能应该被考虑。
SELECT A, col_date
FROM TABLENAME t_ext
ORDER BY col_date DESC NULLS LAST
FETCH FIRST 1 ROW ONLY;
< p > NULLS LAST 是为了防止您的字段中可能存在空值而设置的。


-6
SELECT mu_file, mudate
  FROM flightdata t_ext
 WHERE mudate = (SELECT MAX (mudate)
                     FROM flightdata where mudate < sysdate)

这似乎与问题不符合? - Nathan Tuggy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接