Трехстороннее соединение с использованием одной таблицы SQL - PullRequest
3 голосов
/ 26 мая 2011

Предположим, что существует таблица MSSQL UserPost , представляющая что-то, что пользователь опубликовал, со следующими полями:

ID | dateAdded | parentPostID | postBody

Пользователь в системе можетсоздайте запрос , получите ответ , а затем другие пользователи могут комментарий к ответу .То есть запрос <= 1: many => Reponse <= 1: many => Комментарий (подумайте о вопросе StackOverlow> Ответ> Комментарий похож на модель).

Все сообщения пользователя ( Запрос , Ответ и Комментарий ) представлены UserPost строк, где запрос имеет parentPostID = null;;Ответы parentPostID - это идентификатор запроса, а комментарии parentPostID - это идентификатор ответа.

Мне нужно вывести все простым способом:

Request 1
- Response A
-- Comment (i)
-- Comment (ii)
- Response B
-- Comment (i)
Request 2
...

Вопрос : какой оператор SQL возвращает необходимую информацию наиболее удобным способом?

Я пытаюсь написать трехстороннее соединение между (UserPosts) как Запросы [join] (UserPosts) как Ответы [join] (UsersPosts) как Комментарии, но я не уверен, что это самый простой способ.

Бонус : возможно ли это сделать с помощью C # Linq?

1 Ответ

5 голосов
/ 26 мая 2011

Не могу придумать, как это сделать в LINQ.Я удалил неиспользуемые столбцы.К счастью, это ограниченная иерархия.Я использую новый тип данных hierarchyid, который имеет желаемый порядок сортировки:

create table UserPosts (
    ID int not null,
    ParentID int null
)
go
insert into UserPosts (ID,ParentID)
select 1,null union all
select 2,null union all
select 3,1 union all
select 4,2 union all
select 5,3 union all
select 6,1 union all
select 7,6
go
select
    *
from
    UserPosts up
        left join
    UserPosts up_1st
        on
            up.ParentID = up_1st.ID
        left join
    UserPosts up_2nd
        on
            up_1st.ParentID = up_2nd.ID
order by
    CONVERT(hierarchyid,
    COALESCE('/' + CONVERT(varchar(10),up_2nd.ID),'') +
    COALESCE('/' + CONVERT(varchar(10),up_1st.ID),'') +
    '/' + CONVERT(varchar(10),up.ID) + '/'
    )

HierarchyID (в виде строк) выглядят как /GrandParent/Parent/Child/ - поэтому мы создаем значения, которые выглядят так.Очевидно, что если у нас нет прародителя (up_2nd.ID равно нулю, так как мы не можем получить 2 левых соединения, как описано), то мы просто хотим построить /Parent/Child/ - это то, что 1-й КОАЛИС помогает нам достичь,Точно так же, если мы не можем найти каких-либо родителей (оба значения up_1st.ID и up_2nd.ID равны нулю), тогда оба COALESCE просто превращаются в пустые строки, и мы в конечном итоге создаем /ID/.


Вы можете добавить:

CASE
    WHEN up_2nd.ID is not null then 'Comment'
    WHEN up_1st.ID is not null then 'Response'
    ELSE 'Request'
END as Level

в список выбора, если вы хотите отслеживать, на каком уровне находится элемент (или вместо этого использовать цифры, если хотите)

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