在某些字段上查找重复项,排除其他字段(Oracle / SQL)

时间:2014-03-12 21:03:11

标签: sql oracle

我有一个供应商表,我用它来查找重复的条目。我的数据的一个例子如下(仅感兴趣的领域)。

+-----------+-------------+---------+--------------+
| Vendor_No | Vendor_Name | Address | Bank_Acct_No |
+-----------+-------------+---------+--------------+
| 01        | First       | abc     | 123          |
| 01        | First       | abc     | 123          |
| 02        | Second      | def     | 456          |
| 03        | Second      | def     | 456          |
+-----------+-------------+---------+--------------+

要查找重复值,我会从Vendor_Name,Address和Bank_Acct_No中删除特殊字符。然后我使用以下内容:

select a.Vendor_No
     , a.Vendor_Name
     , a.Address
     , a.Bank_Acct_No
     , COUNT(*) OVER (PARTITION BY a.Vendor_Name, a.Address, a.Bank_Acct_No) as Dupe_Group1
     , DENSE_RANK() OVER (ORDER BY a.Vendor_Name, a.Address, a.Bank_Acct_No) as Group1
from vendor_data a

如果Dupe_Group1大于1,则发现重复。然后Group1对重复值具有相同的值。这是一个相当不错的系统,但在上面的示例中,我希望排除前两行被视为重复,因为它们具有相同的Vendor_No值。另一方面,最后两个将被视为重复。

有没有办法获取我的代码并排除Vendor_No相同但仍保留在我的结果中的实例(我需要它来识别供应商)?


编辑:

我也会对Bank_Acct_No上的重复进行相同的分析(这个例子的结果看起来相同,但是如果有更多的数据,它会改变某些东西可能是group2中的欺骗而不是group1)。代码是:

select a.Vendor_No
     , a.Vendor_Name
     , a.Address
     , a.Bank_Acct_No
     , COUNT(*) OVER (PARTITION BY a.Vendor_Name, a.Address, a.Bank_Acct_No) as DupeGrp1
     , DENSE_RANK() OVER (ORDER BY a.Vendor_Name, a.Address, a.Bank_Acct_No) as Grp1
     , COUNT(*) OVER (PARTITION BY a.Bank_Acct_No) as DupeGrp2
     , DENSE_RANK() OVER (ORDER BY a.Bank_Acct_No) as Grp2
from vendor_data a

所需的结果集将是:

+-----------+-------------+---------+--------------+----------+------+----------+------+
| Vendor_No | Vendor_Name | Address | Bank_Acct_No | DupeGrp1 | Grp1 | DupeGrp2 | Grp2 |
+-----------+-------------+---------+--------------+----------+------+----------+------+
| 01        | First       | abc     | 123          | 1        | 1    | 1        | 1    |
| 01        | First       | abc     | 123          | 1        | 2    | 1        | 2    |
| 02        | Second      | def     | 456          | 2        | 3    | 2        | 3    |
| 03        | Second      | def     | 456          | 2        | 3    | 2        | 3    |
+-----------+-------------+---------+--------------+----------+------+----------+------+

1 个答案:

答案 0 :(得分:1)

我不确定为什么你在结果集中拥有所有这些计数和排名。如果你想知道记录是否重复,但是在一个标志中说明了这一点。您的逻辑是,如果两个记录具有相同的vendor_nameaddressbank_account_no ,并且它们具有不同的vendor_no,则它们是重复的。所以使用这个逻辑:

select a.Vendor_No, a.Vendor_Name, a.Address, a.Bank_Acct_No,
       (case when min(Vendor_No) over (PARTITION BY a.Vendor_Name, a.Address, a.Bank_Acct_No) <>
                  max(Vendor_No) over (PARTITION BY a.Vendor_Name, a.Address, a.Bank_Acct_No)
             then 1
             else 0
        end) as IsDup
from vendor_data a;

事实证明,比较min()max()值就足够了。如果有两个不同的值(假设没有考虑NULL),那么至少有两行。