在一个选择中找到“朋友的朋友”关系(SUBSELECT和/或JOIN)

时间:2013-09-02 08:57:51

标签: mysql

我有一个“关系”矩阵,如:

+---------+------------+------------+------------+------------+------------+
| name    | Albert     | Bob        | Charles    | Dale       | Ethan      |
+---------+------------+------------+------------+------------+------------+
| Albert  |            |    0       |    1       |    1       |   -1       |
| Bob     |            |            |    1       |   -1       |    1       |
| Charles |            |            |            |    0       |    1       |
| Dale    |            |            |            |            |    0       |
| Ethan   |            |            |            |            |            |
+---------+------------+------------+------------+------------+------------+
 0 means they don't know each other
 1 means they like each other
-1 means they don't like each other

现在,我想输入两个名字并获得众所周知的人数,并通过将'喜欢'相加来“推测”他们的关系(最好是在一个SELECT中)。


例如,拿一对Charles和Dale:

  

查尔斯知道阿尔伯特和鲍勃,他们也认识戴尔。他们的关系   自查尔斯以来,查尔斯和戴尔之间可能很友好   喜欢Albert(+1)谁喜欢Dale(+1)而Charles喜欢Bob(+1)   虽然鲍勃不喜欢戴尔(-1)。

     

因此,输出将是2个相互已知的人和+3的“推测”。


我无法理解功能性的子选择查询,加上矩阵只有半填充的事实似乎使它更复杂(有时名称是第一个索引,有时它是第二个)。 / p>

有人可以帮我制定一个有用的查询吗?

1 个答案:

答案 0 :(得分:1)

根据上面的评论,您应该将您的表格结构修改为更合理的内容。 所以我们假设表格如下:

- 列:(PersonId,Name)

PersonRelationships - 列:(Person1Id,Person2Id,Relationship)

然后查询可能如下:

DECLARE @Person1Id INT;
DECLARE @Person2Id INT;
SET @Person1Id = 1;
SET @Person2Id = 2;

SELECT SUM(r1.Relationship + r2.Relationship)
(
    SELECT 
      Person2Id AS CommonRelatedPersonId, Relationship
    FROM PersonRelationships
    WHERE Person1Id = @Person1Id
    UNION 
    SELECT 
      Person1Id AS CommonRelatedPersonId, Relationship
    FROM PersonRelationships
    WHERE Person2Id = @Person1Id
) r1
JOIN 
(
    SELECT 
      Person2Id AS CommonRelatedPersonId, Relationship
    FROM PersonRelationships
    WHERE Person1Id = @Person2Id
    UNION 
    SELECT 
      Person1Id AS CommonRelatedPersonId, Relationship
    FROM PersonRelationships
    WHERE Person2Id = @Person2Id
) r2 ON r1.CommonRelatedPersonId = r2.CommonRelatedPersonId;

请原谅任何语法错误 - 我更习惯MS SQL Server语法。 仍然你应该能够看到这个概念 - 你需要一个关系表,链接人,你需要假设链接可以在任何一个方向(因此上面的工会)

在共同相关人员上加入2个联合(A-> B + B - > A)副本并总计总数,并且你在那里。