SQL 服务器迭代 CTE
SQL Server Iterate through CTE
存储过程 #1:@Country
参数 returns 1+ 行 OrganizationID
和 MeasurableID
列
存储过程 #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
存储过程 #1:@Country
参数 returns 1+ 行 OrganizationID
和 MeasurableID
列
存储过程 #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