010_递归

010_递归

 

 

-- create Employees table and insert values

IF OBJECT_ID('Employees') IS NOT NULL

DROP TABLE Employees

GO

CREATE TABLE Employees

(

 empid INT NOT NULL,

 mgrid INT NULL,

 empname VARCHAR(25) NOT NULL,

 salary MONEY NOT NULL

)

GO

IF OBJECT_ID('Departments') IS NOT NULL

DROP TABLE Departments

GO

-- create Departments table and insert values

CREATE TABLE Departments

(

 deptid INT NOT NULL PRIMARY KEY,

 deptname VARCHAR(25) NOT NULL,

 deptmgrid INT

)

GO

 

-- fill datas

INSERT INTO employees VALUES  (1,NULL,'Nancy',00.00)

INSERT INTO employees VALUES  (2,1,'Andrew',00.00)

INSERT INTO employees VALUES  (3,1,'Janet',00.00)

INSERT INTO employees VALUES  (4,1,'Margaret',00.00)

INSERT INTO employees VALUES  (5,2,'Steven',00.00)

INSERT INTO employees VALUES  (6,2,'Michael',00.00)

INSERT INTO employees VALUES  (7,3,'Robert',00.00)

INSERT INTO employees VALUES  (8,3,'Laura',00.00)

INSERT INTO employees VALUES  (9,3,'Ann',00.00)

INSERT INTO employees VALUES  (10,4,'Ina',00.00)

INSERT INTO employees VALUES  (11,7,'David',00.00)

INSERT INTO employees VALUES  (12,7,'Ron',00.00)

INSERT INTO employees VALUES  (13,7,'Dan',00.00)

INSERT INTO employees VALUES  (14,11,'James',00.00)

 

INSERT INTO departments VALUES  (1,'HR',2)

INSERT INTO departments VALUES  (2,'Marketing',7)

INSERT INTO departments VALUES  (3,'Finance',8)

INSERT INTO departments VALUES  (4,'R&D',9)

INSERT INTO departments VALUES  (5,'Training',4)

INSERT INTO departments VALUES  (6,'Gardening',NULL)

GO

 

SELECT * FROM employees

SELECT * FROM departments

 

-- table-value function

IF OBJECT_ID('fn_getsubtree') IS NOT NULL

DROP FUNCTION  fn_getsubtree

GO

CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT)

RETURNS TABLE

AS

RETURN(

  WITH Employees_Subtree(empid, empname, mgrid, lvl)

  AS

  (

    -- Anchor Member (AM)

    SELECT empid, empname, mgrid, 0

    FROM employees

    WHERE empid = @empid  

    UNION ALL

    -- Recursive Member (RM)

    SELECT e.empid, e.empname, e.mgrid, es.lvl+1

    FROM employees AS e

       join employees_subtree AS es

          ON e.mgrid = es.empid

  )

    SELECT * FROM Employees_Subtree

)

GO

 

-- cross apply query

SELECT *   

FROM Departments AS D

    CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST

   

-- outer apply query

SELECT *

FROM Departments AS D

    OUTER APPLY fn_getsubtree(D.deptmgrid) AS ST

   

   

SELECT *

FROM Departments d

OUTER APPLY (SELECT * FROM employees e WHERE d.deptmgrid=e.mgrid) q

 

 

 

 

select *from dbo.Customers as C outer apply   

(select top 2 *     from dbo.Orders as O    

where C.customerid=O.customerid     order by orderid desc) as CA

 

 

 

CREATE TABLE [aaa](

  [id] [int] NULL,

  [pid] [int] NULL,

  [name] [nchar](10)

 )

 GO

 INSERT INTO aaa VALUES(1,0,'a')

 INSERT INTO aaa VALUES(2,0,'b')

 INSERT INTO aaa VALUES(3,1,'c')

 INSERT INTO aaa VALUES(4,1,'d')

 INSERT INTO aaa VALUES(5,2,'e')

 INSERT INTO aaa VALUES(6,3,'f')

 INSERT INTO aaa VALUES(7,3,'g')

 INSERT INTO aaa VALUES(8,4,'h')

 GO

 

--下面的Sql是查询出1结点的所有子结点

with my1 as(select * from aaa where id = 1

  union all select aaa.* from my1, aaa where my1.id = aaa.pid

 )

 select * from my1 --结果包含1这条记录,如果不想包含,可以在最后加上:where id <> 1

 

--下面的Sql是查询出8结点的所有父结点

with my1 as(select * from aaa where id = 8

  union all select aaa.* from my1, aaa where my1.pid = aaa.id

 )

 select * from my1

 

 

--eg:

CREATE TABLE [tb](

     [qj] [int] NULL,    -- 月份,本测试假设从1月份开始,并且数据都是连续的月份,中间没有隔断

    [je] [int] NULL,    -- 本月销售实际金额

    [rwe] [int] NULL,    -- 本月销售任务额

    [fld] [float] NULL    -- 本月金额大于任务额时的返利点,返利额为je*fld

 ) ON [PRIMARY]

--现在要求计算每个月的返利金额,规则如下:

--1月份销售金额大于任务额  返利额=金额*返利点

--2月份销售金额大于任务额  返利额=(金额-1月份返利额)*返利点

--3月份销售金额大于任务额  返利额=(金额-1,2月份返利额)*返利点

--以后月份依次类推,销售额小于任务额时,返利为0

 

--具体的Sql如下:

WITH    my1

          AS ( SELECT   * ,

                        CASE WHEN je > rwe THEN ( je * fld )

                             ELSE 0

                        END fle ,

                        CAST(0 AS FLOAT) tmp

               FROM     tb

               WHERE    qj = 1

               UNION ALL

               SELECT   tb.* ,

                        CASE WHEN tb.je > tb.rwe

                             THEN ( tb.je - my1.fle - my1.tmp ) * tb.fld

                             ELSE 0

                        END fle ,

                        my1.fle + my1.tmp tmp -- 用于累加前面月份的返利

               FROM     my1 ,

                        tb

               WHERE    tb.qj = my1.qj + 1

             )

    SELECT  *

    FROM    my1

*/

posted @ 2015-02-10 21:49  黑白叹  阅读(86)  评论(0编辑  收藏  举报