避免连接中的重复 (Oracle)

Avoid duplication in a join (Oracle)

我必须加入 2 tables。

我必须在 table 2 中找到参数值才能将其添加到我的 table 1 中。 但这是一个历史 table,形式也是如此:

object  value   date 
1       232     24/10/2020    
1       111     11/06/2019          
2       231     22/09/2011 
2       545     05/09/2020
...     ...     ...

如何编写连接查询以避免重复并只获取最后一个日期的值?

我试过一些像:

select a.*, b.value
from tableA a, (select value, object max(date) from tableB group by object, value)b
where a.object = b.oject

但是错了

非常感谢。

可以用row_number()生成序号,然后选择第一个:

select a.*, b.value
from tableA a join
     (select b.*, row_number() over (partition by object order by date desc) as seqnum
      from tableB
     ) b
     on a.object = b.object and seqnum = 1;

注意:学习使用正确、明确、标准、可读的JOIN语法。 从不FROM 子句中使用逗号。

您需要从第二个 table 中获得的内容可以在单个聚合子查询中完成:

select a.*, b.value
from   tableA a
       join (
              select object, 
                     max(value) keep (dense_rank last order by date_col) as value
              from   tableB
              group  by object
            ) b
       on a.object = b.object
;

如果 tableB 中可能有 (object, date_col) 的重复项,则“最近的值”可能不明确(“最近的日期”可能出现不止一次)。查询将 select “最新值”中的最高值;您可以根据需要更改它(如果这甚至是一个可能的问题)。此外,如果 date_col 可能为 null,您可能需要在聚合函数中的 order by date_col 之后添加 nulls first

我写date_col是因为date是保留关键字,所以不能是列名。或许“对象”也是如此。我希望您实际上没有名为 OBJECT 和 DATE 的列,对吗?

您可以使用ROW_NUMBER功能过滤掉不需要的记录如下:

SELECT *
  FROM (
    SELECT A.*,
           B.VALUE,
           ROW_NUMBER() OVER(PARTITION BY B.OBJECT ORDER BY B.DATE DESC NULLS LAST) AS RN
      FROM TABLEA   A
      JOIN TABLEB   B ON A.OBJECT = B.OJECT
) WHERE RN = 1