获取最大日期行的 SQL 查询

Posted

技术标签:

【中文标题】获取最大日期行的 SQL 查询【英文标题】:SQL query to get the maximum dated row 【发布时间】:2020-07-31 12:39:15 【问题描述】:

我有一个查询,它为我的员工提供了不同日期的多行 -

PROCESSSTARTDATE  EMPLOYEENUMBER RUN_ACTION  CURRENTAMOUNT
10-JUL-2020          27             D           10
11-JUL-2020          27             C           10.3
12-JUL-2020          27             F           11.6

11-JUL-2020          28             C           2.8
12-JUL-2020          28             F           2
13-JUL-2020          28             G           11.6

用于上述输出的查询-

Select pa.processstartdate,
paam.assignment_number EMPLOYEENUMBER,
pr.RUN_ACTION RUN_ACTION,
pa.CURRENTAMOUNT
from
per_all_actions pa,
per_all_assignments_m paam,
per_run pr
where pa.action_id = pr.action_id
and paam.assignment_id = pr.assignment_id

我只想要输出中的最大 PROCESSSTARTDATE 行。即

PROCESSSTARTDATE  EMPLOYEENUMBER RUN_ACTION  CURRENTAMOUNT
12-JUL-2020          27             F           11.6
13-JUL-2020          28             G           11.6

怎么做?

【问题讨论】:

你为什么选择不使用正确的、明确的、标准的、可读的JOIN格式? 这是 Oracle 专有的连接语法。 Oracle 在 2001 年的 9i 版本中实现了 ANSI JOIN(标准)格式。但是使用的格式不是专有的,因为其他 RDBMS 也允许使用它。但它在那时已经过时了。 【参考方案1】:

在 Oracle 中,您可以使用带有 keep 关键字的聚合:

Select max(pa.processstartdate) as processstartdate,
       paam.assignment_number as EMPLOYEENUMBER,
       max(pr.RUN_ACTION) keep (dense_rank first order by pa.processstartdate desc) as RUN_ACTION,
       max(pa.CURRENTAMOUNT) keep (dense_rank first order by pa.processstartdate desc) as current_amount
from per_all_actions pa join
     per_run pr
     on pa.action_id = pr.action_id join
     per_all_assignments_m paam
     on paam.assignment_id = pr.assignment_id
group by paam.assignment_number

【讨论】:

【参考方案2】:

您可以使用rank 获取每位员工的最新行。附带说明一下,隐式连接(在 from 子句中有多个表)是一种过时的做法,您可能应该改用显式 join 子句:

SELECT processstartdate, employeenumber, run_action, currentamount
FROM   (SELECT pa.processstartdate AS processstartdate,
               paam.assignment_number AS employeenumber,
               pr.run_action AS run_action,
               pa.currentamount AS currentamount,
               RANK() OVER (PARTITION BY paam.assignment_number 
                            ORDER BY processstartdate DESC) AS rk
        FROM   per_all_actions pa
        JOIN   per_run pr ON pa.action_id = pr.action_id
        JOIN   per_all_assignments_m paam ON paam.assignment_id = pr.assignment_id) t
WHERE  rk = 1

【讨论】:

【参考方案3】:

使用row_number窗口子句添加伪列,按员工分组并按日期降序排列。

然后将其包装在一个子查询中,您只会看到 row_number=1。

类似:

select *
  from (select pa.processstartdate,
               paam.assignment_number EMPLOYEENUMBER,
               pr.RUN_ACTION RUN_ACTION,
               pa.CURRENTAMOUNT,
               row_number() over(partition by paam.assignment_number order by pa.processstartdate desc) as rn
          from per_all_actions pa, per_all_assignments_m paam, per_run pr
         where pa.action_id = pr.action_id
           and paam.assignment_id = pr.assignment_id) t
 where t.rn = 1

【讨论】:

以上是关于获取最大日期行的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql 如何获取数据表中离当前日期最近的数据

基于一个值获取特定行的 SQL 查询

如何检索表的值以获取sql中两列的最大值

用于获取 ID1 的最新条目的 SQL 查询

SQL Server:从最大日期/最新日期的记录中获取数据

自 DST 日期起获取行的正确方法?