【问题标题】:Get most recent record from Right table with sub query使用子查询从右表中获取最新记录
【发布时间】:2021-10-17 16:06:18
【问题描述】:

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

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

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 匹配。

干杯

【问题讨论】:

  • 有几个问题。一是B.xx1 可能在功能上不依赖于GROUP BY 术语,并且您的数据库(Oracle)不能很好地处理间接功能依赖,因此您的SELECT A.* 可能会成为问题。提供create table 语句,以及每个表的约束。
  • 请分享示例数据和所需的输出。
  • 对不起,但是 - 这真的是 Oracle 吗? “PROC SQL”和“QUIT”表明它不是(至少,我从未见过前者,而后者用于“退出”你的 SQL*Plus 会话,但是 - 对我来说 - 它看起来好像它“终止了” " PROC SQL 语句 ...
  • @not_that_simple 。 . .我真的不明白你的问题。您的查询有很多逻辑,不仅仅是获取最新的行。这个逻辑在问题中没有解释。目前还不清楚您要做什么。样本数据和期望的结果会有所帮助。您还需要解释基本的事情,例如您如何识别最近的记录。
  • @Littlefoot、PROC_SQLQUIT 是 SAS 语言中使用的专有词。它的扩展之一是 PROC_SQL,它允许 SAS 程序与支持 ANSI SQL 的数据库进行交互。

标签: sql oracle sas proc-sql


【解决方案1】:

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

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

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

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

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

最后,您可以按 1 过滤结果以返回最新结果,但如果您对每个 ID 的前 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 是您的下一列。这意味着您的系统不必在每次运行时都执行昂贵的排序,但这取决于您是否计划经常使用此查询以及它占用了多少开销。

【讨论】:

  • 做到了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2016-10-15
  • 2011-10-26
  • 2013-06-14
  • 2018-01-25
  • 2014-05-12
相关资源
最近更新 更多