我有一个名为Report
的表格,Report
中的列如下:
Id(char)
Name(char)
ParentId(char)
Sequence(int)
SortBy(char)
该表有一些层次结构。每行的ParentId
是另一行Id
(顶层的ParentId
为NULL)。 SortBy
字段为"Name"
或"Sequence"
。
现在我想要一个SELECT * FROM Report
。我希望获得的结果是ParentId
分组,但在每个组中,它按SortBy
排序,其中SortBy
的值在行ID =此组'中s ParentId。
更具体地说,如果某个群组的ParentId
为"animal"
,那么该ID为SortBy
的行的"animal"
为"Name"
,我希望此群组是按"Name"
排序。
有人可以帮忙吗?非常感谢你的时间!
答案 0 :(得分:2)
select r.*
from Report r
left join Report p on p.ID = r.ParentID
order by r.ParentID,
case p.SortBy
when 'Sequence' then right('0000000000' + cast(r.Sequence as varchar(10)), 10)
else r.Name
end
答案 1 :(得分:2)
您可以在订单中使用CASE
按父项动态排序。您的案例唯一棘手的问题是您可以排序的列是不同的数据类型。在这种情况下,您必须将它们转换为通用数据类型。
查询很简单。左连接到父级并使用父级确定案例中的第二个排序参数。第一个排序参数是parentId
- 它将孩子们组合在一起。
有两种方法可以处理Sequence
。您可以将其转换为varachar并使用pad,或添加第三个sort参数。执行计划没有变化,但如果Sequence
列索引
SELECT Child.*
FROM #Report [Child]
LEFT JOIN #Report [Parent] ON Parent.Id = Child.ParentId
ORDER BY
Child.ParentId,
CASE Parent.SortBy WHEN 'Name' THEN Child.Name END,
Sequence -- sort by sequence if no column is matched
替代ORDER BY
ORDER BY
Child.ParentId,
CASE Parent.SortBy
WHEN 'Name' THEN Child.Name
ELSE RIGHT('0000000000' + CAST(Child.Sequence AS VARCHAR), 10)
END
IF EXISTS (SELECT * FROM tempdb.sys.objects WHERE NAME LIKE '#Report%')
DROP TABLE #Report;
CREATE TABLE #Report
(
Id CHAR(20),
Name CHAR(20),
ParentId CHAR(20),
Sequence INT,
SortBy CHAR(20)
);
INSERT INTO #Report VALUES
('a', 'zName', 'f', 2, ''),
('b', 'bName', 'f', 3, ''),
('c', 'cName', 'g', 7, ''),
('d', 'dName', 'g', 5, ''),
('e', 'eName', 'g', 6, ''),
('f', 'fName', '', 9, 'Name'),
('g', 'gName', '', 8, 'Sequence');
Id Name ParentId Sequence SortBy
f fName 9 Name
g gName 8 Sequence
b bName f 3
a zName f 2
d dName g 5
e eName g 6
c cName g 17
答案 2 :(得分:1)
这是使用RANK OVER
和UNION
SELECT Child.*, RANK() OVER (PARTITION BY Child.ParentID ORDER BY Child.Sequence) AS Ranked
FROM Report Child
LEFT JOIN Report Parent ON Parent.ID = Child.ParentID
WHERE Parent.SortBy = 'Sequence'
ORDER BY Child.ParentID, Ranked
SELECT Child.*, RANK() OVER (PARTITION BY Child.ParentID ORDER BY Child.Name) AS Ranked
FROM Report Child
LEFT JOIN Report Parent ON Parent.ID = Child.ParentID
WHERE Parent.SortBy = 'Name'
ORDER BY Child.ParentID, Ranked