我正在尝试创建一个SQL语句,它将在SilkCentral Test Manager中重新创建分层容器/文件夹/测试结构。
此查询将生成所有测试容器,文件夹和测试:
SELECT "NodeID", "ParentID", "Name", "IsLeaf", "OrderNumber"
FROM "Silk"."TM_TestPlanNodes" AS TPN
WHERE PROJECTID = 36
ORDER BY "ParentID", "OrderNumber", "IsLeaf"
以下是一些结果:
NodeID ParentID Name IsLeaf OrderNumber
65408 Installation and Upgrades 0 0
65445 Connectivity 0 1
65448 Focus 0 2
65409 GINA / PLAP 0 3
65446 Graphical User Interface 0 4
71038 Login Properties 0 5
65449 Miscellaneous 0 6
70636 Net Firewall 0 7
70998 Software Updates 0 8
65447 Third-party Services 0 9
70805 SilkTest Automated Tests 0 10
68812 65408 0. Setup 0 0
65454 65408 1. Installations & Upgrades 0 1
65450 65408 Typical/Custom Installation 0 2
我希望这个订购代替:
ParentID已排序,但如果存在具有ParentID = thePreviousNode'sID的节点,则接下来选择该节点。如果有多个节点,则应由IsLeaf和OrderNumber订购。
如何做到这一点?我的能力非常有限,因为我认为非常复杂的语法最终会在Silk中引发错误。我打算尝试嵌套的SELECT语句:
SELECT "NodeID", "ParentID", "Name","IsLeaf"
FROM "Silk"."TM_TestPlanNodes"
WHERE PROJECTID = '36'AND ParentID LIKE (
SELECT ParentID
FROM "Silk"."TM_TestPlanNodes"
WHERE NAME = 'Installation and Upgrades')
但是这会出现这样的错误:“无法执行报告查询:子查询返回的值超过1。当子查询跟随=,!=,<,< =,>,> =时,不允许这样做或者当子查询用作表达式时。“
这就是为什么我在摆弄Order By。
答案 0 :(得分:2)
您可以使用递归cte创建隐藏列并按该列排序。隐藏列应该是类似的东西:
WITH cte (NodeID, ParentID, Name, IsLeaf, [Order])
AS
(
SELECT NodeID, ParentID, Name, IsLeaf, cast(NodeID as nvarchar(10))
FROM "Silk"."TM_TestPlanNodes"
WHERE PROJECTID = '36'
UNION ALL
SELECT "NodeID", "ParentID", "Name","IsLeaf", cast(leftNode.ParentID as nvarchar(10)) + cast(leftNode.NodeID as nvarchar(10))
FROM "Silk"."TM_TestPlanNodes" as leftNode
INNER JOIN cte on cte.NodeID = leftNode.ParentID
WHERE leftNode.ParentID = cte.NodeID
)
select "NodeID", "ParentID", "Name","IsLeaf" from cte
order by cast([Order] as nvarchar(50))
这是用记事本写的,所以可能有一些错误,但想法是制作一个[order]
列,例如 65530 将 654086554569530 (parent_parent,父节点和节点)
修改强>:
只有当id长度为5个字符时才有效,但是从这里你可以进行适当的调整。
答案 1 :(得分:1)
尽管它可能不是一个完美的契合,但它与自联合列表中的父子记录的嵌套分层表示非常接近,并且包含了正确的排序问题。您可能需要为您的表稍微调整一下,但here's a link to a prior solution
澄清菜单和相应数据的问题。
id | parentid | name
1 | 0 | CatOne
2 | 0 | CatTwo
3 | 0 | CatThree
4 | 1 | SubCatOne
5 | 1 | SubCatOne2
6 | 3 | SubCatThree
期望的输出
CatOne 1
--SubCatOne 4
--SubCatOne2 5
CatTwo 2
CatThree 3
--SubCatThree 6
第一种情况是基于父母对所有类似ID进行预分组......因此,当父ID为0时,它是最顶层的,所以我们保留它的ID。然后,在它下面的任何孩子,我们想要他们各自的PARENT ID,所以所有相同的都被正确预先分组。
SECOND group by的目的是强制将表示实际TOP LEVEL菜单项的条目放在列表顶部,而不管子条目如何。
假设您有一个已经建立了ID的表,现在您将新项目添加到位置ID = 7,用于“新顶级”,并希望将ID#2和3移动到新的“顶部” -level section 。如果您只是使用第一个CASE查询,您的记录将被模拟返回为
ID Parent Name (natural order from the table)
2 7 CatTwo
3 7 CatThree
7 0 New Category. (we want THIS one in FIRST POSITION of the group)
正如您所看到的,这将是子分组顺序的错误表示。顶级项目实际上位于第3位...为了将它带到前面,我们现在进行子分组并说...如果记录的父ID = 0,则将其排序为好像它是'1'优先级。其他任何东西都被认为是'2'优先级,并会像
那样模拟结果ID Parent Name SubPrioritySort
7 0 New Category. 1
2 7 CatTwo 2
3 7 CatThree 2
由于您实际上并未在结果查询中返回这些“CASE”值,否则您无法直观地看到它...但是对于grins,请将它们作为列添加到查询中以查看其影响。希望这能为你澄清答案。
在您的问题中,您显然可以将排序顺序列添加到此查询的基础中。