2013-05-31 6 views
6

Я пытаюсь выяснить, как написать запрос для SQL Server, который используется для соответствия общим словам. Имена находятся в двух столбцах в одной таблице. Только «приемные» друзья должны быть возвращены.SQL Server: найти общие элементы в 2 столбцах

Вот пример информации из базы данных:

ID  Name_1  Name_2  Accepted 
===================================== 
1  Jimmy  John  1 
2  John  Joey  1 
3  Joey  Jimmy  1 
4  John  Sally  1 
5  Jimmy  Sally  0 

В этом примере Джимми дружит с Джоном. Другим другом между этими двумя (и желаемым результатом) является Джо. Салли распространена и для обоих, но Джимми еще не принял ее как друга.

+0

У вас есть пример того, что вы уже пробовали уже? – HABO

ответ

0

Несколько менее элегантный вид, но, возможно, более исполнительское решение может быть:

DECLARE @person1 VARCHAR(50) = 'Jimmy' 
DECLARE @person2 VARCHAR(50) = 'John' 

SELECT FriendsOfP1.Name as MutualFriend 
FROM (SELECT A.name_2 AS Name 
      FROM  friends A 
      WHERE  (A.name_1 = @person1) 
        AND Accepted = 1 
        AND name_2 <> @person2 
      UNION ALL 
      SELECT A.name_1 
      FROM  friends A 
      WHERE  (A.name_2 = @person1) 
        AND Accepted = 1 
        AND name_1 <> @person2) AS friendsOfP1 
INNER JOIN (SELECT A.name_2 AS Name 
      FROM friends A 
      WHERE (A.name_1 = @person2) 
        AND Accepted = 1 
        AND name_2 <> @person1 
      UNION ALL 
      SELECT A.name_1 
      FROM friends A 
      WHERE (A.name_2 = @person2) 
        AND Accepted = 1 
        AND name_1 <> @person1) AS FriendsOfP2 
ON  FriendsOfP1.Name = FriendsOfP2.Name 
+0

Работает впервые! –

+0

ваше решение, похоже, работает лучше. Благодаря! –

3

Try с этой двойной автообъединение для взаимной дружбы:

SELECT Friend_1, Friend_2, COMMON 
FROM 
(
SELECT f2.NAME_1 AS Friend_1 
     ,f1.NAME_2 AS Friend_2 
     ,f2.Name_2 AS COMMON 
FROM friends f1 
INNER JOIN friends f2 
ON f1.NAME_1 = f2.NAME_2 
WHERE f1.accepted = 1 AND f2.accepted = 1 
) T 
INNER JOIN FRIENDS F3 
ON (F3.Name_1 = Friend_1 AND F3.Name_2 = Friend_2) 
OR (F3.Name_2 = Friend_1 AND F3.Name_1 = Friend_2) 
WHERE F3.ACCEPTED <> 0 AND Friend_1 = 'John' AND Friend_2 = 'Jimmy' 

COMMON является общим другом.

Похожих SQL Fiddle

Примечания: Я не уверен, что эта структура является правильным выбором для проведения такого рода отношения, у вас есть правила о взаимной дружбе, об отказе дружбы, но это выглядит, как вы знаете, ничего об этой информации. Знаете ли вы только частичную информацию или это ваша система хранения/архитектура?

+0

Это решение красивое и компактное, но где я могу указать два имени, чтобы найти общий друг? –

+0

@JohnVanHorn добавить предложение AND во внешнем оберточном запросе, передающем значение параметра из вашего кода или функции SQL. –

Смежные вопросы