现在的位置: 首页 > 综合 > 正文

同一个表中的重复记录

2013年09月09日 ⁄ 综合 ⁄ 共 905字 ⁄ 字号 评论关闭

    今天在写sql脚本时,需要查一个表中的重复记录。这里所谓的重复,指的是某几个字段的值有可能完全相同,也有可能不完全相同。我琢磨了下,突然发现“删除表中重复记录”的思路可以用在这里,结果搞定了今天的这个问题。

    具体解决的问题以及思路就不在这里赘述了,我抽象为下面的问题:

    在一个表中有四个字段:保户ID、出运日期、发票号、发票金额。

    需要实现:找出保户ID和发票号相同的数据(排除出运日期不一致且发票金额不一致的数据)。

    经过思考可以得知,实际上找的是保户ID和发票号相同,且出运日期或发票金额有一个相同的数据。

    如果是要找这四个字段均相同的数据,比较容易处理,直接通过group by就可以实现。但很明显,在这里如果用group by会把简单问题复杂化。再仔细想想问题,发现只需要表和自身进行关联,然后各字段再作为条件进行比较,貌似可以解决问题。但有一个问题,如果是同一个数据行进行比较,肯定会被查找出来,因为同一个数据行的四个字段值肯定完全相等。可不可以把同一数据行的比较排除掉了?答案是肯定的。利用数据库自身的机制可以轻松解决该问题。

    对于oracle数据库,每个数据行都有一个rowid记录数据的物理地址,相当于每个数据行的身份证,不可能重复。因此,在表和自身进行关联比较时,可以通过rowid将同一个数据行的比较排除掉。下面为sql脚本示例:

SELECT DISTINCT T1.INSURANTNO, T1.INVOICENO
                   FROM ALERT_10000021_TMP T1, ALERT_10000021_TMP T2
                  WHERE T1.ROWID <> T2.ROWID /*同一数据行不进行比较*/
                    AND T1.INSURANTNO = T2.INSURANTNO /*保户ID相等*/
                    AND T1.INVOICENO = T2.INVOICENO /*发票号相等*/
                    AND (T1.TRANSPORTDATE = T2.TRANSPORTDATE OR
                      T1.INVOICESUM = T2.INVOICESUM) /*出运日期和发票金额有一个相同就预警*/

    在mysql中,没有rowid,可以用设置主键来替代。

抱歉!评论已关闭.