0

我在 Oracle 中有一个具有重复行的以下查询,其中 file_data 是一个 BLOB 列。

SELECT attachsysfilename, file_seq, version, file_size, lastupddttm, lastupdoprid, file_data 
from PS_LP_EX_FILEATTCH

我想在它上面应用 distinct 子句来获得唯一的记录。但由于 BLOB 列而无法这样做。

有人可以在这方面提供帮助吗?

如何使用 file_data 列上的标量子查询从表中获取 DISTINCT 记录?

4

3 回答 3

0

您可以使用 BLOB 值的散列并按散列分组以及所有其他(非 BLOB)列,从每个组中选择一个pk(或rowid,参见下面的讨论),例如min(pk)or min(rowid),然后选择相应的行从表。

对于散列,您可以使用ora_hash,但这仅适用于学校作业。如果这是一个严肃的项目,您可能需要使用dbms_crypto.hash.

这是否是一个正确的解决方案取决于散列 BLOB 值时发生冲突的可能性。在 Oracle 11.1 - 11.2 中,您可以使用 SHA-1 哈希(160 位);也许这足以区分您的 BLOB 值。在更高的 Oracle 版本中,可以使用更长的哈希(在我的版本 12.2 中最多 512 位)。显然,散列越长,查询越慢 - 但由于冲突,您不会错误地将不同的 BLOB 值识别为“重复”的可能性就越高。

其他响应者询问或提到了表中的一个或多个主键 (pk) 列。如果你有一个,你可以使用它来代替rowid我下面的查询 - 但rowid应该可以正常工作。(不过,如果您的桌子有 pk,则首选。)

dbms_crypto.hash为要使用的散列算法接受一个整数参数(1、2、3 等)。这些在包中被定义为命名常量。唉,在 SQL 中你不能引用包常量;您需要事先找到值。(或者,在 Oracle 12.1 或更高版本中,您可以通过在with子句中包含一个函数来即时执行此操作 - 但让我们保持简单。)

因此,为了涵盖 Oracle 11.1 及更高版本,我假设我们要使用SHA-1算法。要从包中找到它的整数值,我可以这样做:

begin
  dbms_output.put_line(dbms_crypto.hash_sh1);
end;
/

3


PL/SQL procedure successfully completed.

如果您的 Oracle 版本更高,您可以检查 的值hash_sh256,例如;在我的系统上,它是 4。记住这个数字,因为我们将在下面使用它。

查询是:

select {whatever columns you need, including the BLOB}
from   {your table}
where  rowid in (
                  select min(rowid)
                  from   {your table}
                  group  by {the non-BLOB columns},
                            dbms_crypto.hash({BLOB column}, 3)
                )
;

注意hash函数中使用的数字 3 - 这是dbms_crypto.hash_sh1我们之前发现的 的值。

于 2021-02-27T23:06:07.637 回答
0

我使用下面的查询来获取不同的行,包括 BLOB 列。

select
attachsysfilename,
file_seq,
version,
lastupddttm,
lastupdoprid,
file_data,
ROW_NUMBER() OVER (PARTITION BY attachsysfilename,file_seq,version,lastupddttm,lastupdoprid ORDER BY attachsysfilename ,file_seq ,version,lastupddttm DESC,lastupdoprid) RNK
 from ps_lp_ex_fileattch a
 ) WHERE RNK=1
于 2021-03-08T12:02:57.700 回答
0

假设您有 PS_LP_EX_FILEATTCH 表行的主键,您可以使用子查询来获取相关主键的聚合结果

select t.*, ps.file_data 
from (
    SELECT min(pk) my_id
         attachsysfilename
        ,file_seq
        ,version
        ,file_size
        ,lastupddttm
        ,lastupdoprid
    from PS_LP_EX_FILEATTCH
    group by attachsysfilename
        ,file_seq
        ,version
        ,file_size
        ,lastupddttm
        ,lastupdoprid
) t 
inner join PS_LP_EX_FILEATTCH ps ON t.my_id = ps.pk
于 2021-02-27T20:21:56.040 回答