来自底层方法的公用表表达式

时间:2011-10-17 17:24:28

标签: common-table-expression

我有一个Agent表和一个层次表。

CREATE TABLE [dbo].[Agent](
[AgentID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NULL,
[LastName] [varchar](50) NULL,
CONSTRAINT [PK_Agent] 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

CREATE TABLE [dbo].[Hierarchy](
    [HierarchyID] [int] IDENTITY(1,1) NOT NULL,
    [AgentID] [int] NULL,
    [NextAgentID] [int] NULL,
CONSTRAINT [PK_Hierarchy] PRIMARY KEY CLUSTERED 
(
    [HierarchyID] 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 INTO [Agent]([FirstName],[LastName])VALUES('C1','C1');
INSERT INTO [Agent]([FirstName],[LastName])VALUES('C2','C2');
INSERT INTO [Agent]([FirstName],[LastName])VALUES('C3','C3');
INSERT INTO [Agent]([FirstName],[LastName])VALUES('C4','C4');

SELECT * FROM Agent;
AgentID FirstName   LastName
1       C1      C1
2       C2      C2
3       C3      C3
4       C4      C4

- 插入层次结构

INSERT INTO [Hierarchy] ([AgentID],[NextAgentID]) VALUES (1,NULL);
INSERT INTO [Hierarchy] ([AgentID],[NextAgentID]) VALUES (2,1);
INSERT INTO [Hierarchy] ([AgentID],[NextAgentID]) VALUES (3,2);
INSERT INTO [Hierarchy] ([AgentID],[NextAgentID]) VALUES (2,4);
INSERT INTO [Hierarchy] ([AgentID],[NextAgentID]) VALUES (4,NULL);

SELECT * FROM Hierarchy;
HierarchyID AgentID NextAgentID
1       1   NULL
2       2   1
3       3   2
4       2   4
5       4   NULL

我使用公用表表达式来确定从底部到顶部的水平

WITH AgentHierarchy(AgentID, NextAgentID, HierarchyLevel)
AS
(
    SELECT
        H1.AgentID,
        H1.NextAgentID,
        1 HierarchyLevel
    FROM Hierarchy H1
    WHERE NOT EXISTS (SELECT 1 FROM Hierarchy H2 WHERE H2.NextAgentID = H1.AgentID)
    UNION ALL
    SELECT
        H.AgentID,
        H.NextAgentID,
        (AgentHierarchy.HierarchyLevel + 1) HierarchyLevel
    FROM Hierarchy H    
    INNER JOIN AgentHierarchy ON AgentHierarchy.NextAgentID = H.AgentID
)
SELECT DISTINCT
    AgentID,
    NextAgentID, 
    HierarchyLevel
FROM AgentHierarchy
ORDER BY AgentID, NextAgentID, HierarchyLevel;

结果是:

AgentID NextAgentID HierarchyLevel
1       NULL        3
2       1           2
3       2           1
4       NULL        1
2       4           1

我的要求是以下面的方式显示:

AgentID NextAgentID HierarchyLevel
1       NULL        1
2       1           1
3       2           1
3       1           2
4       NULL        1
2       4           1
3       4           2

简而言之,递归所有具有级别的层次结构应该采用从底部到顶部的方法。请帮帮我......

1 个答案:

答案 0 :(得分:0)

我找到了答案:

WITH AgentHierarchy(AgentID, NextAgentID, HierarchyLevel)
AS
(
    SELECT
        H1.AgentID,
        H1.NextAgentID,
        1 HierarchyLevel
    FROM Hierarchy H1
    --WHERE NOT EXISTS (SELECT 1 FROM Hierarchy H2 WHERE H2.NextAgentID = H1.AgentID)
    UNION ALL
    SELECT
        AgentHierarchy.AgentID,
        H.NextAgentID,
        (AgentHierarchy.HierarchyLevel + 1) HierarchyLevel
    FROM Hierarchy H    
    INNER JOIN AgentHierarchy ON AgentHierarchy.NextAgentID = H.AgentID
)
SELECT 
    AgentHierarchy.AgentID,
    NextAgentID, 
    HierarchyLevel
FROM AgentHierarchy
WHERE NOT (NextAgentID IS NULL AND HierarchyLevel > 1);

我做了以下更改:

  1. 删除了锚点查询WHERE子句。
  2. 在UNION之后的第二个选择中添加了CTE的AgentID。
  3. 在CTE中添加WHERE子句以删除垃圾记录 最底层的NULL NextAgentID。
  4. 如果有人有疑问,请告诉我。