2013-06-03 22 views
-1

我有一张表,其中包含一列具有唯一ID和一列与每个唯一ID的配偶ID(如果他们有配偶)。问题是,每个配偶ID也出现在唯一ID列中,所以当我拉出一个列表,试图将一对夫妇作为一个单位来对待时,我经常计算一对夫妇的双重计数。保留一个重复的实例出现在两列中的一列

什么是一个好的,有效的方式来获取给定的唯一ID列表,检查他们的配偶是否也在同一个唯一ID列表中,并且每对夫妇只返回一个唯一的ID?

这个问题有点复杂,有时候夫妻双方都不在同一份名单中,所以如果他们结婚,这不仅仅是一个人的问题。如果配偶不在同一个名单中,我想确保保留那个。我也想确保我保留所有在配偶ID列中具有NULL值的人。在问题表的

子集:

Unique_ID  Spouse_ID 
    1    2 
    2    1 
    3    NULL 
    4    NULL 
    5    10 
    6    25 
    7    NULL 
    8    9 
    9    8 
    10    5 

在该摘录,ID的3,3,4和7都是单。 ID的1,2,5,8和9具有出现在Unique_ID列中的配偶。 ID 6有一个配偶,其ID不出现在Unique_ID列中。所以,我想保留ID的1(或2),3,4,5(或10),6,7和8(或9)。希望这是有道理的。

回答

1

我的倾向是将两个清单合并并删除重复:

select distinct id 
from ((select id 
     from t 
    ) union all 
     (select spouse_id 
     from t 
     where spouse_id in (select id from t) 
    ) 
    ) t 

但是,你的问题问的有效方式。想想这另一种方法是添加新列这是配偶的ID,如果在ID列表或返回NULL(此使用left outer join然后有三种情况:

  1. 没有配偶的ID,所以使用id
  2. id是小于原来的ID,用它。
  3. 配偶ID小于原来的ID。丢弃这个记录,因为原来的被使用。

这里一种明确的表达方式:

select IdToUse 
from (select t.*, tspouse.id tsid, 
      (case when tspouse.id is null then t.id 
        when t.id < tspouse.id then t.id 
        else NULL 
       end) as IdToUse 
     from t left outer join 
      t tspouse 
      on t.spouse_id = tspouse.id 
    ) t 
where IdToUse is not null; 

您可以简化这:

select t.*, tspouse.id tsid, 
     (case when tspouse.id is null then t.id 
       when t.id < tspouse.id then t.id 
       else NULL 
      end) as IdToUse 
    from t left outer join 
     t tspouse 
     on t.spouse_id = tspouse.id 
    where tspouse.id is null or 
     t.id < tspouse.id 
0

两个表只是普通的糟糕的设计
合并表

select id 
from table 
where id < spouseID 
    or spouseID is null 
+0

这是行不通的,但是,因为有时配偶ISN不在同一张名单中。通过只保留小于其配偶身份证的身份证,我可能会丢失本应包含的身份证件。 – Ian

+0

两张桌子简直是不好的设计。合并表格。 – Paparazzi

+0

我不明白你在说什么。数据不在两个表格中。唯一ID和配偶ID是同一个表中的两个独立列。 – Ian

相关问题