Sql 如何从父子表中获取结果
在SQL Server上工作。我的表格结构如下Sql 如何从父子表中获取结果,sql,sql-server,Sql,Sql Server,在SQL Server上工作。我的表格结构如下 CREATE TABLE [dbo].[AgentInfo]( [AgentID] [int] NOT NULL, [ParentID] [int] NULL, CONSTRAINT [PK_AgentInfo] PRIMARY KEY CLUSTERED ( [AgentID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_
CREATE TABLE [dbo].[AgentInfo](
[AgentID] [int] NOT NULL,
[ParentID] [int] NULL,
CONSTRAINT [PK_AgentInfo] PRIMARY KEY CLUSTERED
(
[AgentID] 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
INSERT [dbo].[AgentInfo] ([AgentID], [ParentID]) VALUES (1, -1)
INSERT [dbo].[AgentInfo] ([AgentID], [ParentID]) VALUES (2, -1)
INSERT [dbo].[AgentInfo] ([AgentID], [ParentID]) VALUES (3, 1)
INSERT [dbo].[AgentInfo] ([AgentID], [ParentID]) VALUES (4, 2)
所需输出
使用下面的语法获取所需的输出,但不满足。有没有更好的方法来获得所需的输出
--get parent child list
---step--1
SELECT *
INTO #temp1
FROM ( SELECT a.AgentID ,
a.ParentID,
a.AgentID AS BaseAgent
FROM dbo.AgentInfo a WHERE ParentID=-1
UNION ALL
SELECT a.ParentID ,
0 as AgentID,
a.AgentID AS BaseAgent
FROM dbo.AgentInfo a WHERE ParentID!=-1
UNION ALL
SELECT a.AgentID ,
a.ParentID,
a.AgentID AS BaseAgent
FROM dbo.AgentInfo a
WHERE ParentID!=-1
) AS d
SELECT * FROM #temp1
DROP TABLE #temp1
帮助我改进语法。如果你有任何问题,请提问 您可以使用递归
选择,请参见中的示例,从示例D开始
递归WITH
的总体思路是:首先选择一个作为起点,然后是一个UNION ALL,第二个select
描述从上一级到下一级的步骤,如果上一级可以是第一次选择的结果,也可以是第二次选择的上一次运行的结果,您可以尝试以下操作,以获得元素树:
WITH CTE_AgentInfo(AgentID, ParentID, BaseAgent)
AS(
SELECT
AgentID,
ParentID,
AgentID AS BaseAgent
FROM AgentInfo
WHERE ParentID = -1
UNION ALL
SELECT
a.AgentID,
a.ParentID,
a.AgentID AS BaseAgent
FROM AgentInfo a
INNER JOIN CTE_AgentInfo c ON
c.AgentID = a.ParentID
)
SELECT * FROM CTE_AgentInfo
下面是一个演示。请尝试以下内容:
WITH Merged (AgentId, ParentId) AS (
SELECT AgentId, ParentId FROM AgentInfo WHERE ParentId = -1
UNION ALL
SELECT AgentInfo.AgentId, AgentInfo.ParentId FROM AgentInfo INNER JOIN Merged ON AgentInfo.AgentId = Merged.ParentId
)
SELECT * FROM Merged
WITH [Parents]([AgentID], [ParentID], [BaseAgent])
AS
(
SELECT
[AgentID],
[ParentID],
[AgentID] AS [BaseAgent]
FROM [AgentInfo]
WHERE [ParentID] = -1
UNION ALL
SELECT
[ai].[AgentID],
[ai].[ParentID],
[p].[BaseAgent]
FROM [AgentInfo] [ai]
INNER JOIN [Parents] [p]
ON [ai].[ParentID] = [p].[AgentID]
)
SELECT *
FROM [Parents]
ORDER BY
[BaseAgent] ASC,
[AgentID] ASC
您可以使用a来执行此操作
sql语句将如下所示:
WITH Merged (AgentId, ParentId) AS (
SELECT AgentId, ParentId FROM AgentInfo WHERE ParentId = -1
UNION ALL
SELECT AgentInfo.AgentId, AgentInfo.ParentId FROM AgentInfo INNER JOIN Merged ON AgentInfo.AgentId = Merged.ParentId
)
SELECT * FROM Merged
WITH [Parents]([AgentID], [ParentID], [BaseAgent])
AS
(
SELECT
[AgentID],
[ParentID],
[AgentID] AS [BaseAgent]
FROM [AgentInfo]
WHERE [ParentID] = -1
UNION ALL
SELECT
[ai].[AgentID],
[ai].[ParentID],
[p].[BaseAgent]
FROM [AgentInfo] [ai]
INNER JOIN [Parents] [p]
ON [ai].[ParentID] = [p].[AgentID]
)
SELECT *
FROM [Parents]
ORDER BY
[BaseAgent] ASC,
[AgentID] ASC
但是,结果与期望的输出不同,因为每个代理只列出一次。
输出为:
AGENTID PARENTID BASEAGENT
1 -1 1
3 1 1
2 -1 2
4 2 2
小提琴演奏完了
下面是一篇关于使用层次结构的好文章:什么是baseagent
列?我认为这是用于多根树选择的。。。我建议通过使用嵌套集。它们更容易选择,选择速度更快。如果你的树确实经常改变,那就没有那么好了。我不明白,如果代理3和代理4的父级为1和2,那么为什么代理1和代理2的父级也为3和4。子对象不能是其父对象的父对象。这里有些东西很让人困惑。安德烈斯·奥托谢谢你的回复,请检查我的回复。这个更正更没有意义。。。BaseAgent列现在完全关闭。你的基本代理是1和2,对吗?