根据多年的记录寿命选择记录的多个实例

spa*_*boy 3 performance sql-server-2005 sql-server query-performance

我有一个包含原始日期和寿命的项目表。我想创建一个过程来选择需要在特定持续时间内替换的所有项目。我觉得在单个选择的 where 子句中有一种数学方法可以做到这一点。我能想到的唯一方法是迭代多年并附加将要替换的项目......这似乎超级缓慢且效率低下。我应该如何处理这个问题?


每个评论请求的详细信息:

数据库引擎: SQL Server 2005

源表:

CREATE TABLE Items
(
    ID int,
    ItemName varchar(255),
    InstallYear int,
    UsefullLife int
);
Run Code Online (Sandbox Code Playgroud)

所需的存储过程格式:

GetReplacementsWithinYearRange(startyear int, endyear int)
Run Code Online (Sandbox Code Playgroud)

期望的输出:

ItemID - ItemName - ReplaceYear
Run Code Online (Sandbox Code Playgroud)

更多细节:

样本记录:

1  item1  2010  5    
2  item2  2011  6
Run Code Online (Sandbox Code Playgroud)

2010 年至 2030 年范围内的预期结果:

1  item1  2010
1  item1  2015
1  item1  2020
1  item1  2025
1  item1  2030
2  item2  2011
2  item2  2017
2  item2  2023
2  item2  2029
Run Code Online (Sandbox Code Playgroud)

Han*_*non 5

我在这里简化了吗?

CREATE TABLE Items (ItemID int, ItemName nvarchar(255), InstallYear int, Life int)

INSERT INTO Items VALUES (1,'test1',2010,2)
INSERT INTO Items VALUES (2,'test2',2011,2)
INSERT INTO Items VALUES (3,'test3',2012,5)
INSERT INTO Items VALUES (4,'test4',2013,3)

SELECT * FROM Items
GO

CREATE PROCEDURE GetItemLifetimeInfo
(
    @StartYear int,
    @EndYear int
)
AS
BEGIN
    SELECT *, InstallYear + Life AS ReplaceYear 
    FROM Items 
    WHERE InstallYear <= @EndYear AND (InstallYear + Life) >= @StartYear;
END
GO

EXEC GetItemLifetimeInfo 2011, 2022;
Run Code Online (Sandbox Code Playgroud)

返回:

ItemID  ItemName    InstallYear Life    ReplaceYear
1       test1       2010        2       2012
2       test2       2011        2       2013
3       test3       2012        5       2017
4       test4       2013        3       2016
Run Code Online (Sandbox Code Playgroud)

这有效:

CREATE PROCEDURE GetItemLifetimeInfo
(
    @StartYear int,
    @EndYear int
)
AS
BEGIN
    WITH ReplaceYears(ItemID, [Year])
    AS (
        SELECT ItemID, Life
        FROM Items
        UNION ALL
        SELECT Items.ItemID, Items.Life + ReplaceYears.Year
        FROM Items
            INNER JOIN ReplaceYears ON Items.ItemID = ReplaceYears.ItemID
        WHERE ReplaceYears.Year <= (@EndYear - @StartYear)
    )
    SELECT Items.ItemID, InstallYear + ReplaceYears.Year AS ReplaceYear 
    FROM Items
        INNER JOIN ReplaceYears ON Items.ItemID = ReplaceYears.ItemID 
    WHERE InstallYear + ReplaceYears.Year <= @EndYear 
        AND (InstallYear + ReplaceYears.Year) >= @StartYear
    ORDER BY 1,2
END

EXEC GetItemLifetimeInfo 2011,2022;

ItemID  ReplaceYear
1   2012
1   2014
1   2016
1   2018
1   2020
1   2022
2   2013
2   2015
2   2017
2   2019
2   2021
3   2017
3   2022
4   2016
4   2019
4   2022
Run Code Online (Sandbox Code Playgroud)