2

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

帮助我改进我的语法。如果您有任何疑问,请询问。

4

4 回答 4

0

您可以使用递归SELECT,请参阅WITH 文档中的示例,从示例 D 开始。

递归中的一般思想WITH是:您有一个作为起点的第一个选择,然后是一个 UNION ALL 和一个SELECT描述从上一级到下一级的步骤的第二个,其中上一级可以是第一个的结果选择或上一次运行第二个的结果SELECT

于 2013-01-18T08:24:49.483 回答
0

你可以试试这个,得到一个元素树:

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

这是一个SQLFiddle演示来查看它。

于 2013-01-18T08:39:18.880 回答
0

尝试这样的事情:

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
于 2013-01-18T08:40:59.240 回答
0

您可以使用公用表表达式来执行此操作。

然后 sql 语句将如下所示:

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

小提琴在这里

这是一篇关于使用层次结构的好帖子:在关系数据库中存储层次结构数据的选项是什么?

于 2013-01-18T08:51:37.267 回答