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

これを行うには、共通テーブル式を使用できます。

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

ただし、すべてのエージェントが1回だけリストされるため、結果は目的の出力とは異なります。出力は次のとおりです。

AGENTID     PARENTID    BASEAGENT
1           -1          1
3            1          1
2           -1          2
4            2          2

フィドルはここにあります。

そして、ここに階層の操作に関する素晴らしい投稿があります:リレーショナルデータベースに階層データを格納するためのオプションは何ですか?

于 2013-01-18T08:51:37.267 に答える
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

再帰を使用できます。例Dから始まる、WITHのドキュメントSELECTの例を参照してください。

再帰内の一般的な考え方WITHは次のとおりです。開始点となる最初の選択があり、次にUNION ALLと、SELECTレベルから次のレベルへのステップを説明する2番目の選択があります。前のレベルは最初のレベルの結果である可能性があります。または、2番目の前回の実行の結果を選択しますSELECT

于 2013-01-18T08:24:49.483 に答える