首页 > 解决方案 > 使用子查询从右表中获取最新记录

问题描述

当我加入正确的表时,我得到了太多的重复项。我正在尝试从正确的表中获取最新记录,但是,无论我尝试什么它都不起作用。

到目前为止,我已经尝试过:

PROC SQL;
CREATE TABLE fs1.sample AS
    SELECT A.*,
               B.xx1,
           max(B.time_s) 

FROM lx1.results a left join (Select Distinct C.id, c.per FROM lx2.results c 
                          Where c.id = a.id
                              and COMPGED(a.txt1, c.txt1,'i') < 100
                              and c.dt > a.dt
                  and c.ksv = 37
                  and datepart(c.lsg) >= '12DEC2020'd ) b
ON a.id = b.id
group by a.id, a.txt1
QUIT;

不幸的是,我得到一个错误。我也尝试在存在时使用案例,但这需要的时间太长了。本质上,我试图根据 time_s 从正确的表中获取最新记录。我还想确保我从右表中获取的记录与 a.txt1 有点匹配。

干杯

标签: sqloraclesasproc-sql

解决方案


当您执行连接时,您会附加表中与您的连接条件匹配的所有记录。

如果对表进行了适当的索引,子查询可以实现获取最新值的目标,但是,如果查询使用错误的索引,则 TOP 或等效函数可能会返回错误的结果。

有许多方法可以完成检索最新记录的任务,但它们取决于几件事。

首先,您需要能够识别最近的行是什么,通常通过名为 CreatedDate 的列或类似的 ID 来识别。(你应该知道那个业务逻辑是什么,它可能是按时间顺序输入的表[就像大多数表一样],因此,SubID 可能是一个东西。我们假设它是 CreatedDate。)

其次,您需要根据 CreatedDate 对行进行降序排列,以便最新匹配的 ID 排名第 1。

最后,按 1 过滤结果以返回最新结果,但如果您对每个 ID 的前 x 个最新返回结果感兴趣,也可以按 <= x 过滤。

使用更多的数学语言:我们从 CreatedDate 和 ID 值派生一个值,然后使用该派生值对数据进行排序和过滤。在这种情况下,我们按每个 ID 的降序从 CreatedDate 派生 RowNumber。

为了实现这一点,您可以使用窗口函数 ROW_NUMBER(),

ROW_NUMBER() OVER (PARTITION BY id ORDER BY CreatedDate DESC) as RankID

此窗口函数将为每个 ID 以降序返回相对于 CreatedDate 的行值,其中最新创建的日期等于 1。

然后,您可以在整个查询周围放置方括号,使其成为一个表格,以便您能够过滤该窗口函数的结果。

SELECT id, txt
    (SELECT id, txt
     ,ROW_NUMBER() OVER (PARTITION BY id ORDER BY CreatedDate DESC) as RankID
      FROM SourceTable) A
WHERE RankID = 1

这应该可以实现您返回“最新结果”的目标。

你的列是什么决定了数据相对于 ID 的年龄,它可以是多个,应该放在 ORDER BY 中。

为了使这个查询执行得更快,您应该适当地索引您的数据,其中 ID 是第一列,CreatedDate Desc 是您的下一列。这意味着您的系统不必在每次运行时都执行昂贵的排序,但这取决于您是否计划经常使用此查询以及它占用了多少开销。


推荐阅读