2

我试图创建一个 sql 查询,它将在我的数据库中检测(可能)重复的客户:

我有两张桌子:

  1. 具有以下列的客户:cid、名字、姓氏、zip。请注意, cid 是此表的唯一客户 ID 和主键。
  2. IgnoreForDuplicateCustomer具有以下列:cid1、cid2。两列都是外键,引用了 Customer(cid)。这张表是用来说cid1的客户和cid2的客户是不一样的。

例如,如果我有

  • cid = 1、firstname="foo"、lastname="anonymous" 和 zip="11231" 的客户条目
  • 以及另一个带有 cid=2、firstname="foo"、lastname="anonymous" 和 zip="11231" 的客户条目。

所以我的 sql 查询应该搜索具有相同名字、姓氏和 zip 的客户,并且检测到 cid = 1 的客户与 cid = 2 的客户相同。

但是,通过设置 cid1 = 1 和 cid2 = 2 在 IgnoreForDuplicateCustomer 表中存储一个新条目,应该可以说客户 cid = 1 和 cid=2 不同。

所以检测重复的客户可以很好地使用这个 sql 查询脚本:

SELECT cid, firstname, lastname, zip, COUNT(*) AS NumOccurrences
       FROM Customer
 GROUP BY fistname, lastname,zip
       HAVING ( COUNT(*) > 1 )

我的问题是,我无法将 IgnoreForDuplicateCustomer 表集成到之前的示例中,因为有一个条目/规则,所以 cid = 1 和 cid=2 的客户不会被标记/查询为相同在 IgnoreForDuplicateCustomer 表中。

所以我尝试通过添加 where 子句来扩展我之前的查询:

    SELECT cid, firstname, lastname, COUNT(*) AS NumOccurrences
               FROM Customer    
    WHERE cid NOT IN (
                     SELECT cid1 FROM IgnoreForDuplicateCustomer WHERE cid2=cid 
                     UNION 
                     SELECT cid2 FROM IgnoreForDuplicateCustomer WHERE cid1=cid
                     )  
     GROUP BY firstname, lastname, zip
     HAVING ( COUNT(*) > 1 )

不幸的是,这个额外的 WHERE 子句对我的结果完全没有影响。有什么建议么?

4

3 回答 3

1

根据 TPete 的评论进行编辑(不要尝试):

SELECT 
    C1.cid, C1.firstname, C1.lastname
FROM 
    Customer C1,
    Customer C2
WHERE
    C1.cid < C2.cid AND 
    C1.firstname = C2.firstname AND 
    C1.lastname = C2.lastname AND 
    C1.zip = C2.zip AND 
    CAST(C1.cid AS VARCHAR)+' ' +CAST(C2.cid AS VARCHAR) <> 
       (SELECT CAST(cid1 AS VARCHAR)+' '+CAST(cid2 AS VARCHAR) FROM IgnoreForDuplicateCustomer I WHERE I.cid1 = C1.cid AND I.cid2 = C2.cid);

最初我认为这IgnoreForDuplicateCustomer是客户表中的一个字段。

于 2012-02-21T13:57:20.957 回答
1

这个给你:

Select a.*
From (
  select c1.cid 'CID1', c2.cid 'CID2'
  from Customer c1 
  join Customer c2 on c1.firstname=c2.firstname 
    and c1.lastname=c2.lastname and c1.zip=c2.zip
    and c1.cid < c2.cid) a
Left Join (
  Select cid1 'CID1', cid2 'CID2'
  From ignoreforduplicatecustomer one
 Union
  Select cid2 'CID1', cid1 'CID2'
  From ignoreforduplicatecustomer two) b on a.cid1 = b.cid1 and a.cid2 = b.cid2
where b.cid1 is null

这将为您提供 table 中重复记录的 ID customer,这些记录不在 table 中ignoreforduplicatecustomer

经测试:

CREATE TABLE IF NOT EXISTS `customer` (
 `CID` int(11) NOT NULL AUTO_INCREMENT,
 `Firstname` varchar(50) NOT NULL,
 `Lastname` varchar(50) NOT NULL,
 `ZIP` varchar(10) NOT NULL,
 PRIMARY KEY (`CID`)) 
ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=100 ;

INSERT INTO `customer` (`CID`, `Firstname`, `Lastname`, `ZIP`) VALUES
(1, 'John', 'Smith', '1234'),
(2, 'John', 'Smith', '1234'),
(3, 'John', 'Smith', '1234'),
(4, 'Jane', 'Doe', '1234');

和:

CREATE TABLE IF NOT EXISTS `ignoreforduplicatecustomer` (
 `CID1` int(11) NOT NULL,
 `CID2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


INSERT INTO `ignoreforduplicatecustomer` (`CID1`, `CID2`) VALUES
(1, 2);

我的测试设置的结果是:

CID1  CID2
 1     3
 2     3
于 2012-02-21T19:35:37.753 回答
0

疯了,但我认为它有效:)

首先我在名称上加入客户表以获取重复项然后我排除 IgnoreForDuplicateCustomer 表上的键(联合是因为第一个查询返回 cid1、cid2 和 cid2、cid1

结果将被重复,但我认为您可以获得所需的信息

select c1.cid, c2.cid
from Customer c1 
     join Customer c2 on c1.firstname=c2.firstname 
     and c1.lastname=c2.lastname and c1.zip=c2.zip
     and c1.cid!=c2.cid
except 
(
    select cid1,cid2 from IgnoreForDuplicateCustomer
    UNION
    select cid2,cid1 from IgnoreForDuplicateCustomer
)

第二枪:

select firstname,lastname,zip from Customer 
group by firstname,lastname,zip 
having (count(*)>1)
except
select c1.firstname, c1.lastname, c1.zip
from Customer c1 join IgnoreForDuplicateCustomer IG on c1.cid=ig.cid1 join Customer c2 on ig.cid2=c2.cid

第三:

select firstname,lastname,zip from (
    select firstname,lastname,zip from Customer 
    group by firstname,lastname,zip 
    having (count(*)>1)
) X
where firstname not in (
select c1.firstname
from Customer c1 join IgnoreForDuplicateCustomer IG on c1.cid=ig.cid1 join Customer c2 on ig.cid2=c2.cid
)
于 2012-02-21T14:02:26.113 回答