Sql 如何从父子表中获取结果

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_

在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_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,对吗?