SQL Server: как выбрать контакты первой, второй и третьей степени - PullRequest
4 голосов
/ 24 апреля 2011

Я работаю над проектом социального веб-сайта, и мне нужно перечислить «Контакты первой, второй и третьей степени» моих контактов.Я использую SQL Server и C #

Предположим, что таблица contact выглядит следующим образом:

enter image description here

Для контактов первой степени:

  • Если 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, которое объясняет контактуровень.

Спасибо за ответы.

Ответы [ 3 ]

2 голосов
/ 24 апреля 2011

Что затрудняет выбор контактов моих контактов, которые не являются контактами моей первой степени.

Можно использовать оператор 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 вернуть все результаты первого 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.

1 голос
/ 24 апреля 2011

Вот мой подход:

  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, если это необходимо.

0 голосов
/ 24 апреля 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...