3

我们有一个看起来像这样的表:

CREATE TABLE Hierarchy (EmployeeID int not null, parentID int, orderlimit int)
CREATE TABLE Order (EmployeeID int not null, OrderSize int)

它应该告诉你每个员工对订单的批准范围,我们决定将员工经理的ID保留在同一记录中,因为如果订单超过一个人的限制,他/她的经理(简称parentID)应该批准它。

如果再次超过上一级,则该订单应向上一级,以此类推,直到达到其有资格批准该订单的级别。如果parentID一个人为空,这意味着他是管理结构中的最高级别,我们不知道我们可能有多少个可能的级别,如果最高级别'

为了澄清考虑这一点

INSERT INTO Hierarchy values 
(1,10,0),
(2,11,0),
(3,12,0),
(10,20,100),
(11,21,300),
(12,22,200),
(20,30,1000),
(21,31,2000),
(22,31,3000),
(30,40,10000),
(31,40,15000),
(40,NULL,NULL)

我们想创建一个返回如下内容的视图:

EmployeeID       ApprovalGoesTo     LowerLimit    UpperLimit
------------------------------------------------------------
1                10                  0             99
1                20                  100           999
1                30                  1000          9999
1                40                  10000         NULL
2                11                  0             299
2                21                  300           1999
2                31                  2000          14999
2                40                  15000         NULL
.
.
.
10               10                  0             100
10               20                  101           1000
10               30                  1001          10000
.
.
.
31               31                  0             15000
31               40                  15001         NULL
40               40                  0             NULL

所以,一个订单 ORDER VALUES (1, 8999)应该去employeeID : 30

所有值都是正数,并且查询不应绑定到层次结构的级别。

我们不想使用游标,这意味着,我们要严格使用基于集合的操作,因为在这种情况下性能非常重要。

  1. 这可以用 CTE 完成吗?还是干脆加入?子查询?嵌套查询?
  2. 有什么改进设计的建议吗?

请记住,我们需要一个独立于层次结构级别的答案。

4

1 回答 1

1

递归 CTE 答案...

Create  View OrderApprovalHierachy
As
With    cte As
(
        Select  h1.employeeID, 
                h1.parentID, 
                h2.parentID As parentsparent, 
                h2.orderlimit
        From   (Select  *
                From    hierarchy n1
                Union
                Select  employeeID, 
                        employeeID as parentID, 
                        orderlimit
                From    hierarchy n2) h1
        Left    Join hierarchy h2
                On  h1.parentID = h2.EmployeeID
        Union   All
        Select  h1.employeeID, 
                h1.parentsparent, 
                h2.parentID As parentsparent, 
                h2.orderlimit
        From    cte h1
        Join    hierarchy h2
                On  h1.parentsparent = h2.EmployeeID
        Where   h1.employeeID <> h1.parentID
),      prep As
(
        Select  Row_Number() Over (Partition By EmployeeID Order By IsNull(orderLimit,2147483647) Asc) As pID, 
                EmployeeID, 
                parentID As ApprovalGoesTo, 
                orderLimit - 1 As UpperLimit, 
                orderLimit As NextLowerLimit
        From    cte
)
Select  p1.employeeID,
        p1.ApprovalGoesTo, 
        IsNull(p2.NextLowerLimit,0) As LowerLimit,
        p1.UpperLimit
From    prep p1
Left    Join prep p2
        On  p1.EmployeeID = p2.EmployeeID
        And p1.pID = p2.pID + 1
Where   IsNull(p1.UpperLimit,0) <> -1
And     p1.ApprovalGoesTo Is Not Null
于 2013-05-08T17:39:38.810 回答