我有一个分类表和一个阶段表。每个类别都与某些阶段相关联,每个阶段可能有也可能没有子阶段。
这是SQL模式的样子:
CREATE TABLE Category
(
Id BIGINT,
Name VARCHAR(100),
Ordinal BIGINT
)
CREATE TABLE Stages
(
Id BIGINT,
Name VARCHAR(100),
CategoryId BIGINT,
ParentStage BIGINT,
Ordinal BIGINT
)
我正在尝试编写查询,以便按正确顺序获取Category,Stage和ChildStages。
这就是我想要的:
Category Stage
-----------------------------
Cat1 Cat1Stage1
Cat1 Cat1Stage2
Cat1 Cat1Stage3
Cat1 Cat1Stage3ChildStage1
Cat1 Cat1Stage3ChildStage2
Cat1 Cat1Stage3ChildStage3
Cat1 Cat1Stage4
Cat1 Cat1Stage5
Cat2 Cat2Stage1
Cat2 Cat2Stage2
Cat2 Cat2Stage3
Cat2 Cat2Stage3ChildStage1
Cat2 Cat2Stage3ChildStage2
Cat2 Cat2Stage3ChildStage3
Cat2 Cat2Stage4
Cat2 Cat2Stage5
这是我写的查询,但没有按顺序给我结果:
SELECT Category.Name 'Category Name',
Stages.Name 'Stage Name'
FROM Category
LEFT JOIN Stages
ON Category.Id = Stages.CategoryId
ORDER BY Category.Ordinal,
CASE WHEN ParentStage IS NULL THEN Stages.Ordinal ELSE ParentStage END
http://sqlfiddle.com/#!3/d8c2d
我缺少连接顺序的子句吗?
答案 0 :(得分:2)
起初看起来有点奇怪,但这里有:
Stages
做了第二次左连接以找到当前舞台的父级。这确保父级可以立即跟随其子级,前提是没有多个子级的子级大于任意选择的大型子级。
所以,这是查询的样子:
SELECT c.Name 'Category Name',
s.Name 'Stage Name'
FROM Category c
LEFT JOIN Stages s
ON c.Id = s.CategoryId
left join Stages ps
on s.ParentStage = ps.Id
ORDER BY c.Ordinal,
case
when ps.Id is null then s.Ordinal * 1000
else ps.Ordinal * 1000 + s.Ordinal
end
答案 1 :(得分:2)
下面使用传统方法在递归CTE中使用路径计算:
;WITH cteStages AS(
SELECT *,
Path=cast(row_number() over (partition by ParentStage order by Ordinal) as varbinary(max))
FROM Stages
WHERE ParentStage is null
UNION ALL
SELECT s.*,
c.Path + cast(row_number() over (partition by s.ParentStage order by s.Ordinal) as binary(8))
FROM Stages s
JOIN cteStages c ON s.ParentStage = c.Id
)
SELECT c.Name [Category Name], s.Name [Stage Name]
FROM Category c
JOIN cteStages s ON c.Id = s.CategoryId
ORDER BY c.Ordinal, s.Path