从包含互惠关系的表中提取唯一对

时间:2009-06-02 22:13:13

标签: sql sql-server-2005 tsql

考虑一个 SQL Server 2005 数据库,其中包含许多人的大量数据,其中很大一部分是已婚。为了跟踪人与人之间的关系,存在一个关系表,用于将一个人的ID与另一个人的ID相关联。每个关系记录上的关系类型用于表示两个人之间存在的关系类型(duh):“已婚”,“是儿子”,“是”的女儿,等

对于已婚人士,表中有两个关系记录 - 一个显示人A与人B结婚,另一个记录显示人B与人A结婚。对于婚姻,虽然在数据库中存在一些未经回复的记录,但是没有两个记录将被视为错误。 (这是一种继承的设计,我没有改变这种方法的自由。)

RelID  Person1  Person2  RelationshipType
-----------------------------------------
1      1001     1010     Married           //Reciprocated by RelID 4
2      1002     1011     Married           //Reciprocated by RelID 5
3      1003     1012     Married           //Reciprocated by RelID 6
4      1010     1001     Married           //Reciprocated by RelID 1
5      1011     1002     Married           //Reciprocated by RelID 2
6      1012     1003     Married           //Reciprocated by RelID 3
7      1004     1013     Married           //Not properly reciprocated

我需要做的是从表中提取独特的已婚夫妇。

我创建了一个名为 GetOrderedPair(val1,val2) 的函数,它接受2个人ID并按顺序返回两个值的逗号分隔字符串值。这样,它总是返回相同的字符串值,无论我是否得到,参考上面的示例数据,来自记录的Person1和Person2,RelID为1或RelID为4(往复记录对)。

我不禁想到有一种更好的方式让我望而却步。使用这个功能是最好的方法吗?你还能推荐什么?

当然,谢谢你提前。 : - )

2 个答案:

答案 0 :(得分:6)

由于你已经封装了GetOrderPair,我不知道它背后的逻辑,但我至少会告诉你我做的事情:

select distinct
    case when Person1 > Person2 then Person2 else Person1 end as Person1,
    case when Person1 > Person2 then Person1 else Person2 end as Person2
from
    couples
where
    relationshiptype = 'Married'

也许有人比我做得更好。

答案 1 :(得分:1)

说实话,我并不完全明白你的问题是什么。一般来说,要获取已婚夫妇的名单,你会做一个简单的查询:

SELECT p1.*, p2.*
FROM   Person AS p1
JOIN   Relationship r ON p1.PersonID = r.Person1 AND r.RelationshipType = 'Married'
JOIN   Person AS p2 ON r.Person2 = p2.PersonID
WHERE  p1.PersonID < p2.PersonID  --This would ensure that you only get each couple "once"

这是你正在寻找的那种东西吗?