在视图中使用递归CTE

时间:2016-06-17 16:42:56

标签: sql sql-server recursion view common-table-expression

拥有典型的父/子层次结构表,使用Common Table Expression查询它是很常见的事情:

 with CTE  as (
    select Id, ProviderId, ConsumerId
    from T1
    where ProviderId in (2, 3, 9)

    union all
    select T1.Id, T1.ProviderId, T1.ConsumerId
    from T1  
    join CTE on C.ProviderId = CTE.ConsumerId 
)
select * from CTE

是否可以基于此查询创建视图,以便人们可以执行:

select * from MagicView where ProviderId in (2,3,9)

换句话说,我们能以某种方式从CTE的锚点部分提取参数来创建一般视图吗?

2 个答案:

答案 0 :(得分:3)

创建一个TVF:

CREATE FUNCTION my_function (
    @ProviderId int
)
RETURNS @ProviderTable TABLE 
(
    Id int NULL, 
    ProviderId int NULL,
    ConsumerId int NULL
)
AS 
BEGIN
    WITH cte AS (
        SELECT  Id, 
                ProviderId, 
                ConsumerId
        FROM T1
        WHERE ProviderId in (@ProviderId)
        UNION ALL
        SELECT  t.Id, 
                t.ProviderId, 
                t.ConsumerId
        FROM T1 t 
        INNER JOIN cte c 
            ON t.ProviderId = c.ConsumerId 
    )

    INSERT INTO @ProviderTable
    SELECT * FROM cte;

    RETURN;
END;

创建视图:

CREATE VIEW my_view
AS 
SELECT m.*
FROM Providers p
CROSS APPLY my_function (p.ProviderId) m

之后,您可以从视图中选择所需的任何内容:

SELECT * 
FROM my_view 
WHERE ProviderId in (2,3,9)
OPTION (MAXRECURSION 0)

答案 1 :(得分:1)

表格值路线的一种方法

CREATE FUNCTION [dbo].[MVParam_tvf](@ParameterString nvarchar(4000), @Delimiter char(1)= ',')
RETURNS @VALUES TABLE (Param nvarchar(4000))AS

Figure out your code preference to spilt delimited string to table

END

CREATE FUNCTION dbo.MagicView_tvf
(   
    @ParameterString  NVARCHAR(4000)
    ,@Delimiter CHAR(1)
)
RETURNS TABLE 
AS
RETURN 
(
    with CTE  as (
       select Id, ProviderId, ConsumerId
       from
          T1 t
          INNER JOIN MVParam_tvf (@ParameterString, @Delimiter) p
          ON CAST(t.ProviderId AS VARCHAR(10)) = p.OutPutColumn

       union all
       select T1.Id, T1.ProviderId, T1.ConsumerId
       from T1  
       join CTE on C.ProviderId = CTE.ConsumerId 
    )
    select * from CTE
)
GO

SELECT * FROM dbo.MagicView_tvf ('2,3,9')

如果你想去视图路线创建没有cte的锚点部分的where行的视图,那么当你调用它时,在那个查询上写下你的where语句。

相关问题