Вот как я бы это сделал.Вот некоторые упрощенные данные:
if object_id('tempdb.dbo.#Posts') is not null drop table #Posts
create table #Posts
(
PostId char(1),
OwnerUserId int,
AcceptedAnswerUserId int
)
insert into #Posts
values
('A', 1, 2),
('B', 2, 1),
('C', 2, 3),
('D', 2, 4),
('E', 3, 1),
('F', 4, 1)
Для наших целей мы не очень заботимся о PostId
, и в качестве отправной точки мы имеем набор упорядоченных пар владельцев постов (OwnerUserId
) и принятые ответчики (AcceptedAnswerUserId
).
(хотя это и необязательно, вы можете визуализировать набор следующим образом)
select distinct OwnerUserId, AcceptedAnswerUserId
from #Posts
Теперь мы хотим найти все записи в этом наборекоторые имеют эти два поля поменялись местами.Т.е. где владелец одного поста является принятым ответчиком другого.Поэтому, когда пара равна (1, 2), мы хотим найти (2, 1).
Я сделал это с левым соединением, чтобы вы могли видеть строки, которые оно пропускает, но меняя его на внутреннее соединениеограничит его набором, который вы описали.Вы можете собирать информацию по своему усмотрению (либо выбрав любой из столбцов из шапки, либо, если вы хотите, чтобы они были в одной строке, возвращая оба столбца точно из одной из таблиц).
select
u1.OwnerUserId,
u1.AcceptedAnswerUserId,
u2.OwnerUserId,
u2.AcceptedAnswerUserId
from #Posts u1
left outer join #Posts u2
on u1.AcceptedAnswerUserId = u2.OwnerUserId
and u1.OwnerUserId = u2.AcceptedAnswerUserId
Редактировать Если вы хотите исключить самостоятельные ответы, просто добавьте and u1.AcceptedAnswerUserId != u1.OwnerUserId
к предложению on
.
В личной заметке мне всегда было смешно, как глубоко укоренился SQLи реляционная алгебра в теории множеств, и все же выполнение операций на основе множеств, подобных этой, в SQL имеет тенденцию быть очень неуклюжим.Главным образом потому, что для сохранения неупорядоченности вы должны представлять элементы набора в одном столбце.Но затем, чтобы сравнить элементы набора в SQL, вам нужно представить элементы набора в виде отдельных столбцов.
Теперь подумайте, как вы можете распространить это на триады пользователей, комментирующих один и тот же пост?