4

我正在做一个社交网站项目,我需要列出我的联系人的“一级、二级和三级联系人”。我正在使用 SQL Server 和 C#

假设这样的contact表:

在此处输入图像描述

一级接触:

  • 如果gulsah是我,那么我的第一学位联系人是burak,sennur

我用来选择这个的查询:

SELECT contact_2 FROM Contacts_Table WHERE contact_1 like 'gulsah'

二级联系人:

如果gulsah再次是我,那么我的第二学位联系人是: mali

困难的是从我的联系人中选择不是我的一级联系人的联系人。

我可以选择相互联系,但我想这不是正确的方法。

例如,要选择我 ( gulsah) 和的相互联系人burak

SELECT contact_1 FROM (SELECT * FROM Contact_Test 
  WHERE contact_2 like 'burak') a
     INNER JOIN (SELECT contact_1 FROM Contact_Test 
     WHERE (contact_2 = 'gulsah')) b 
ON a.contact_1 = b.contact_1

此查询有效,但正如我所说,这不是这项工作的正确方法。

三级联系人:

如果gulsah再次是我,那么我的三级联系人是_ mehmet,ahmet

我需要从我的联系人的联系人中选择不是我的一级和二级联系人的联系人:)

这是 Linkedin 的一篇文章,其中解释了联系级别。

感谢您的回复。

4

3 回答 3

2

困难的是从我的联系人中选择不是我的一级联系人的联系人。

您可以使用EXCEPT运算符。

一级联系人:

SELECT contact_2 FROM contact WHERE contact_1 = 'gulsah'

非一级联系人的二级联系人:

SELECT
  contactB.contact_2
FROM 
  contact AS contactB
  INNER JOIN contact AS contactA ON contactA.contact_2=contactB.contact_1
WHERE contactA.contact_1 = 'gulsah'
EXCEPT
SELECT contact_2 FROM contact WHERE contact_1 = 'gulsah'

EXCEPT告诉 SQL Server 返回第一个SELECT中没有出现在第二个中的所有结果SELECT

对于三级联系人(不是一级或二级联系人):

SELECT
  contactC.contact_2
FROM 
  contact AS contactC
  INNER JOIN contact AS contactB ON contactB.contact_2=contactC.contact_1
  INNER JOIN contact AS contactA ON contactA.contact_2=contactB.contact_1
WHERE contactA.contact_1 = 'gulsah'
EXCEPT
(
SELECT contact_2 FROM contact WHERE contact_1 = 'gulsah'
UNION
SELECT
  contactB.contact_2
FROM 
  contact AS contactB
  INNER JOIN contact AS contactA ON contactA.contact_2=contactB.contact_1
WHERE contactA.contact_1 = 'gulsah'
)

我对性能没有寄予厚望,但当然你需要自己检查一下。


作为旁注:

I can select mutual contacts but I guess it is not the right approach.

用于INTERSECT此。

于 2011-04-24T09:02:14.380 回答
1

这是我的方法:

  1. 将我的联系人添加到专门收集的联系人列表中。

  2. 对于Contact_1联系人表中收集的列表中的每个联系人,添加其对应的联系人,Contact_2除非该联系人已经在收集的列表中。

  3. 重复步骤#2 目标度数减一的次数。

  4. 再次重复第 2 步中的查询,但这次只返回结果集(不要将行添加到收集的列表中)。

剧本:

DECLARE @MyContact varchar(50), @DegreeNumber int;
SET @MyContact = 'gulsah';
SET @DegreeNumber = 3;

DECLARE @CollectedContacts TABLE (Contact varchar(50));
INSERT INTO @CollectedContacts (Contact) VALUES (@MyContact);

WHILE @DegreeNumber > 1 BEGIN
  INSERT INTO @CollectedContacts (Contact)
  SELECT ct.Contact_2
  FROM Contacts_Table ct
    INNER JOIN @CollectedContacts cc ON ct.Contact_1 = cc.Contact
    LEFT JOIN @CollectedContacts cc2 ON ct.Contact_2 = cc2.Contact
  WHERE cc2.Contact IS NULL;

  SET @DegreeNumber = @DegreeNumber - 1;
END;

SELECT ct.Contact_2
FROM Contacts_Table ct
  INNER JOIN @CollectedContacts cc ON ct.Contact_1 = cc.Contact
  LEFT JOIN @CollectedContacts cc2 ON ct.Contact_2 = cc2.Contact
WHERE cc2.Contact IS NULL;

如您所见,度数和“我的”联系人都是可参数化的。我正在使用varchar联系人类型,但如果需要,当然可以轻松地将其替换为int

于 2011-04-24T14:53:56.557 回答
0

也许这有帮助: http ://techportal.ibuildings.com/2009/09/07/graphs-in-the-database-sql-meets-social-networks/

于 2011-04-24T09:04:13.000 回答