Distinct vs row_number() - 使用相同条件的查询在oracle中给出不同的结果?

Posted

技术标签:

【中文标题】Distinct vs row_number() - 使用相同条件的查询在oracle中给出不同的结果?【英文标题】:Distinct vs row_number() - query with same condition giving different result in oracle? 【发布时间】:2020-04-02 01:03:17 【问题描述】:

我试图通过两种不同的方法根据同一张表上的三列与一些过滤条件的组合来消除重复,但由于某种原因,两者的查询结果并不相同。

查询 1:

select count(*) 
from (
    select distinct 
        SERIAL_NBR,
        MAC_ADDR,
        UNIT_ADDR 
    from TGT_DEVICE_DETAILS 
    where MODEL_ID = 'ABC' and REC_CREATE_DT_KEY = 20191130
);

结果 - 66181

查询 2:

select count(*) from (
    select 
        xi.*,
        row_number() over (
            partition by xi.SERIAL_NBR,xi.MAC_ADDR,xi.UNIT_ADDR 
            order by test_date_m desc
        ) rownumber 
    from TGT_DEVICE_DETAILS xi
) 
where 
    rownumber  = 1 
    and REC_CREATE_DT_KEY = 20191130 
    and MODEL_ID = 'ABC';

结果 - 65495

两个查询的结果不应该相同吗?如果有人能告诉我我做错了什么会很棒吗?

谢谢, 凯文

【问题讨论】:

只是为了解释为什么结果不同:如果您使用的谓词存在任何三元组 xi.SERIAL_NBR,xi.MAC_ADDR,xi.UNIT_ADDR 以及其他,您可能会得到 row_number =1 的其他谓词,因此它们不会在外部查询中传递 WHERE 子句,因此您最终会得到更少的行。 @gsalem 明白了兄弟!完全错过了。你是对的。 【参考方案1】:

第二个查询在外部查询中有条件REC_CREATE_DT_KEY = 20191130 and MODEL_ID = 'ABC',而在第一个查询中,这些条件在内部查询中。

将条件移至内部查询,您应该会得到相同的结果:

select count(*) from (
    select 
        xi.*,
        row_number() over (
            partition by SERIAL_NBR, MAC_ADDR, UNIT_ADDR 
            order by TEST_DATE_M desc
        ) rownumber 
    from TGT_DEVICE_DETAILS xi
    WHERE REC_CREATE_DT_KEY = 20191130 and MODEL_ID = 'ABC'
) 
where rownumber  = 1;

【讨论】:

感谢您指出这一点。我完全错过了。快速提问,如果我使用上述查询创建了一个没有过滤条件的视图,然后在查询视图时使用了过滤条件,结果是否正确?我真正需要的是消除重复并获得计数。 @KavinPalaniswamy:视图只是底层的 sql 查询,因此行为将是相同的。底线:如果要删除重复项,请使用distinct。这将在您过滤时为您提供一致的结果。

以上是关于Distinct vs row_number() - 使用相同条件的查询在oracle中给出不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章

sql 查询与 Row_Number 不同

述 SQL 中的 distinct 和 row_number() over() 的区别及用法

详述 SQL 中的 distinct 和 row_number() over() 的区别及用法

SQL Server-聚焦ROW_NUMBER VS TOP N性能

SQL Server 查询:Union vs Distinct union 所有性能

Oracle 根据特定属性(列)去除重复数据