SQL 服务器迭代 CTE

SQL Server Iterate through CTE

存储过程 #1:@Country 参数 returns 1+ 行 OrganizationIDMeasurableID

存储过程 #2:@OrganizationID@MeasurableID 参数,创建一个 CTE(使用 ROW_NUMBER() OVER (PARTITION BY Entities.ID ORDER BY Contracts.UTCmatched desc) 到 return 每个 Entity 一个单独的行)

我试图将这些组合成一个存储过程,其中 @Country 参数通过 SP1 代码 returns(比如 5)行;然后每一行通过 SP2 代码迭代到 return 单个 table(如果有 20 个实体,则为 100 行)。

我尝试了嵌套和递归 CTE,但均无济于事。我正在考虑 loop/cursor and/or 将最终结果填充到临时 table 但坦率地说我有点迷茫(并且超出了我的经验水平)所以会很感激主要关于采取的方法的建议.

提前致谢。

SP1

        SELECT
            dbo.Measurables.OrganizationID,
            dbo.Measurables.ID AS MeasurableID

            FROM dbo.Measurables INNER JOIN dbo.Organizations ON dbo.Organizations.ID = dbo.Measurables.OrganizationID

            WHERE   dbo.Measurables.EndUTC > SYSUTCDATETIME ( )  
                AND dbo.Measurables.OrganizationID IN
                                        (
                                                SELECT
                                                    dbo.Countries2Organizations.OrganizationID
                                                FROM
                                                    dbo.Countries2Organizations
                                                WHERE
                                                    dbo.Countries2Organizations.Sport IN 
                                                        (
                                                            SELECT
                                                                dbo.Countries2Sports.SportName
                                                            FROM
                                                                dbo.Countries2Sports
                                                            WHERE
                                                                dbo.Countries2Sports.CountryCode = @CountryCode
                                                        )
                                                AND (   dbo.Countries2Organizations.CountryCode = @CountryCode  OR dbo.Countries2Organizations.CountryCode = '')

                                        )

--Result:     OrganizationID     MeasurableID
                    --1                 2017
                    --1                 2018
                    --2                 2021
                    --3                 2023

SP2

;WITH 
        LastScore as ( SELECT Entities.ID, Results.Score,
                                 Results.UTC,   
                                row_number() over (partition by Entities.ID ORDER BY Results.UTC desc) row1
                            FROM dbo.Entities 
                                INNER JOIN dbo.Results ON dbo.Results.EntityID = dbo.Entities.ID
                            WHERE dbo.Results.MeasurableID = @MeasurableID),


        PreviousScore as ( SELECT Entities.ID,  Results.Score,
                                 Results.UTC,   
                                row_number() over (partition by Entities.ID ORDER BY Results.UTC desc) row2
                            FROM dbo.Entities 
                                INNER JOIN dbo.Results ON dbo.Results.EntityID = dbo.Entities.ID
                            WHERE dbo.Results.MeasurableID = @MeasurableID )



    SELECT @OrganizationID AS OrganizationID, @MeasurableID AS MeasurableID, Entities.ID AS EntityID,    
              LastScore.Score AS LastScore, 
                    LastScore.Score - PreviousScore.Score AS Change,    LastScore.UTC 

    FROM Entities 
            LEFT JOIN LastScore on LastScore.ID = Entities.ID AND row1=1
            LEFT JOIN PreviousScore on PreviousScore.ID = Entities.ID AND row2=2

    WHERE dbo.Entities.OrganizationID = @OrganizationID 



--Result:
 --OrganizationID   MeasurableID   EntityID   LastScore   Change   UTC   
      --1              2017           1          15          2    4/6/17
      --1              2017           1          18         -3    4/8/17

我建议使用函数,而不是存储过程 它工作得更快:

1) 没有循环,一次查询就可以取回数据

2) 使用内联函数查询优化器可以优化整个查询

下面是如何使用函数执行此操作的示例:

CREATE FUNCTION dbo.Func1 (
    @Country    INT
)
RETURNS TABLE
RETURN
    SELECT
        dbo.Measurables.OrganizationID,
        dbo.Measurables.ID AS MeasurableID
    FROM dbo.Measurables
...

CREATE FUNCTION dbo.Func2 (
    @OrganizationID  INT,
    @MeasurableID    INT
)
RETURNS TABLE
RETURN
    WITH 
        LastScore as ( SELECT Entities.ID, Results.Score,
                             Results.UTC,   
...


SELECT *
FROM dbo.Func1(@Country)                    F1
CROSS APPLY dbo.Func2(F1.OrganizationID, F1.MeasurableID) F2