Car*_* J. 3 c# sql linq join sql-server-2008
假设有一个MSSQL表UserPost代表用户发布的内容,包含以下字段:
ID | dateAdded | parentPostID | postBody
在系统中的用户可以创建一个请求,接收响应,然后其他用户可以评论的回应.即,Request <= 1:many => Reponse <= 1:many => Comment(想想StackOverlow的问题>答案>评论模型).
所有用户帖子(请求,响应和评论)都由UserPost行表示,其中Request有parentPostID = null;; 响应' parentPostID是请求的ID,而注释parentPostID是响应的ID.
我需要以简单的方式输出所有内容:
Request 1
- Response A
-- Comment (i)
-- Comment (ii)
- Response B
-- Comment (i)
Request 2
...
Run Code Online (Sandbox Code Playgroud)
问题:哪种SQL语句以最有用的方式返回所需信息?
我正在努力将(UserPosts)之间的三向连接写为Requests [join](UserPosts)作为Response [join](UsersPosts)作为Comments但不确定这是最简单的方法.
额外奖励:使用C#Linq可以做到这一点吗?
想不出在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) + '/'
)
Run Code Online (Sandbox Code Playgroud)
HierarchyIDs(作为字符串)看起来像/GrandParent/Parent/Child/- 所以我们构造看起来像这样的值.显然,如果我们没有祖父母(up_2nd.ID是空的,因为我们无法实现所描述的2个左连接),那么我们只想构建/Parent/Child/- 这就是第一个COALESCE帮助我们实现的目标.同样,如果我们不能找到任何父母(双方up_1st.ID和up_2nd.ID为空),则聚结的都只有变成空字符串,而我们最终construcing /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
Run Code Online (Sandbox Code Playgroud)
到您的选择列表,如果您想跟踪该项目的级别(或者如果需要,请使用数字)