【问题标题】:SQL query to get the maximum dated row获取最大日期行的 SQL 查询
【发布时间】: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 也允许使用它。但它在那时已经过时了。

标签: sql oracle oracle-sqldeveloper


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 2015-12-08
        • 1970-01-01
        • 2015-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多