【问题标题】:Finding a better way to get the most recent status寻找更好的方法来获取最新状态
【发布时间】:2021-07-20 23:41:52
【问题描述】:

我有这种方式,我通过获取具有 max(created_on) 日期的相关详细记录来检查最新状态。

它有效,但它看起来很笨拙,我希望找到更好的方法。

select rd.stat_code from rec r, rec_detl rd
where r.id = rd.rec_id
and r.id = 13455478
and rd.id in (
  select id from rec_detl rd1
  where rd1.rec_id = r.id
  and rd1.created_on = (
    select max(created_on) from rec_detl rd2
    where rd2.rec_id = r.id
));

在该示例中,rec_detl 表具有指示状态的 stat_code 列。 rec_detl表有一个外键指向rec表,所以rec表中的每一行对应多条rec_detl记录。

基本上,每次rec记录的状态更新时都会插入一个新的rec_detl。

所以我的问题是“有没有更好、更简单的方法来实现相同的目标并获取最新状态?”和“除了这种方式有点笨拙和丑陋之外,这种方式有什么问题吗?”

【问题讨论】:

  • 你确定最后一个谓词应该是rd2.rec_id = rd.id吗?
  • 您能否描述一下pmt_req_idrec_id 列的确切含义?
  • 输入所需的输出和样本数据
  • @SayanMalakshinov 感谢您指出这一点......我现在更正了。

标签: sql oracle


【解决方案1】:

对于单个记录,您可以使用 fetch first 1 rows only 加法,自 12c 起可用。

select *
from rec_detl
where rec_id = 13455478
order by created_on desc
fetch first 1 rows only

只要不使用rec 表中的任何列,就不需要加入任何内容。

如果您需要rec 列和rec_detl 列用于少量 行并且在rec_detl.rec_id 列上具有索引,这可能适用于横向连接。小是因为这个查询引入了嵌套循环查找。

select *
from rec
  left join lateral(
    select *
    from rec_det
    where rec.id = rec_det.rec_id
    order by created_on desc
    fetch first 1 rows only
  ) q
    on 1 = 1

对于大规模处理,最好使用keep dense_rank first,因为 if 将使用通用连接(通常对于大型数据集将是散列)。但它需要明确列出所有列聚合或分组:

select
  rec.id
  , max(rec.val) as val
  , max(rec_det.status) keep(dense_rank first order by created_on desc) as last_status
from rec
  left join rec_det
    on rec.id = rec_det.rec_id
group by
  rec.id

db小提琴here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    相关资源
    最近更新 更多