CTE 层次结构下降,但从祖先中选取子节点而不是父节点
说明
好的,标题可能有点多:)
我将把脚本粘贴在最后。
想象一下下面的n叉树
.
|
---1 **(25)**
|
-----1.1 **(13)**
| |
| ----1.1.1 (1)
| |
| ----1.1.2 **(7)**
| | |
| | ----1.1.2.1 (4)
| | |
| | ----1.1.2.2 (3)
| |
| ----1.1.3 (5)
|
-----1.2 (2)
|
|
-----1.3 (10)
依此类推,其中根分支“.”还可以有一个 2,3,n 分支,并且该分支也可以有自己的任意树形式,其中任何给定节点都可能有 n 个分支。每个节点末尾括号中的值可以说是该节点处的值。将它们视为带有子帐户的帐户,父帐户是子帐户的总和。
我试图用 CTE 做的是检索直接位于父级下的所有[子]帐户。因此,为了提供 1.1 作为搜索点,它将检索树的整个分支。但是,如果我尝试聪明地对返回值求和,我将将 1.1.2 添加两次(对于此特定示例),一次是通过对其子值求和账户,第二个是其本身所包含的价值的总和。
像这样的事情我该怎么办?
非常感谢:)
以下是脚本:
脚本
表
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Account](
[ID] [nvarchar](50) NOT NULL,
[ParentID] [nvarchar](50) NULL,
[Value] [float] NOT NULL,
[HasChild] [bit] NOT NULL,
CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Account] WITH CHECK ADD CONSTRAINT [FK_Account_Account] FOREIGN KEY([ParentID])
REFERENCES [dbo].[Account] ([ID])
GO
ALTER TABLE [dbo].[Account] CHECK CONSTRAINT [FK_Account_Account]
GO
ALTER TABLE [dbo].[Account] ADD CONSTRAINT [DF_Account_HasChild] DEFAULT ((0)) FOR [HasChild]
GO
CTE 脚本
WITH
DescendToChild([ID],ParentID,Value)
AS
(
--base case
SELECT [ID],ParentID,Value FROM Account
Where ParentID = '1.1'
UNION ALL
----recursive step
SELECT
A.[ID],A.ParentID,A.Value FROM Account as A
INNER JOIN DescendToChild D on A.ParentID = D.ID
)
select * from DescendToChild;
Explanation
OK, the title might be a bit much :)
I'll paste the scripts at the end.
Imagine the following n-ary tree
.
|
---1 **(25)**
|
-----1.1 **(13)**
| |
| ----1.1.1 (1)
| |
| ----1.1.2 **(7)**
| | |
| | ----1.1.2.1 (4)
| | |
| | ----1.1.2.2 (3)
| |
| ----1.1.3 (5)
|
-----1.2 (2)
|
|
-----1.3 (10)
And so on, where the root branch "." can also have a 2,3,n branch and that branch would also have its own arbitrary tree form with n-branches possible from any give node. The values in brackets at the end of each node are the values at the node so to speak. Think of them as accounts with sub-accounts with the parent accounting being the sum of the child-accounts.
What I'm trying to do with CTE is to retrieve all the [sub] accounts directly beneath a parent. So for providing 1.1 as the search point, it'll retrieve that whole branch of the tree. But, if I try to be smart and sum the returned values, I will be adding (for this specific example) 1.1.2 twice, once through the summation of its sub accounts, the second by the summation of the value it itself contains.
How would I go about something like this?
Thanks a zillion :)
Here are the scripts:
Scripts
Table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Account](
[ID] [nvarchar](50) NOT NULL,
[ParentID] [nvarchar](50) NULL,
[Value] [float] NOT NULL,
[HasChild] [bit] NOT NULL,
CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Account] WITH CHECK ADD CONSTRAINT [FK_Account_Account] FOREIGN KEY([ParentID])
REFERENCES [dbo].[Account] ([ID])
GO
ALTER TABLE [dbo].[Account] CHECK CONSTRAINT [FK_Account_Account]
GO
ALTER TABLE [dbo].[Account] ADD CONSTRAINT [DF_Account_HasChild] DEFAULT ((0)) FOR [HasChild]
GO
CTE Script
WITH
DescendToChild([ID],ParentID,Value)
AS
(
--base case
SELECT [ID],ParentID,Value FROM Account
Where ParentID = '1.1'
UNION ALL
----recursive step
SELECT
A.[ID],A.ParentID,A.Value FROM Account as A
INNER JOIN DescendToChild D on A.ParentID = D.ID
)
select * from DescendToChild;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是基于您的示例数据的解决方案。它的工作原理是仅对没有子节点的节点进行求和:
Here's a solution based on your sample data. It works by only summing up those nodes with no children:
http://social. msdn.microsoft.com/Forums/en-US/transactsql/thread/959fe835-e43d-4995-882c-910f3aa0ff68/
http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/959fe835-e43d-4995-882c-910f3aa0ff68/