sql-server - 使用 CTE 代替表变量进行递归函数

标签 sql-server t-sql recursion common-table-expression recursive-query

我正在尝试创建一个循环,当给定零件 ID 时,它将搜索装配零件表并将所有零件放入返回表中。 IE。我想从单个零件 ID 中分解零件。

它需要递归,因为第 1 部分可能有第 2、3、4、5 部分;第 3 部分是包含第 9、10 部分的组装件;部件 10 是与部件 11、23、34、31 组装的部件;第 11 部分是包含第 23、24 部分的组装件。

数据库是SQL Server。

我在这里设置了一些样本日期:http://sqlfiddle.com/#!9/f3cc4f

我期待结果:

part, level
1,    0
2,    1
3,    1
4,    1
9,    2
10,   2
11,   3
23,   3
24,   3

下面是我想出的代码。即使样本数据只有几个级别,我也遇到了最大递归错误。我的完整数据集不应超过 15 个级别。显然有些东西设置不正确,我认为 CTE 可能效果更好。

CREATE FUNCTION [dbo].[fn_getParts] (@source_part_id int, @level int)
RETURNS @parts_list TABLE (
    [part]  int NOT NULL,
    [level] int NOT NULL
)
AS 
BEGIN
    DECLARE
        @max    int = 0,
        @cnt    int = 0,
        @PID    int = 0,
        @Plvl   int = 0,
        @id     int = 0

    DECLARE @chkParts table ([id] int identity(1,1), [PID] int, [level] int)

    INSERT INTO @parts_list VALUES (@source_part_id, @level)

    SET @level += 1

    INSERT INTO @chkParts
        SELECT [Comp_PartID], @level FROM /*visuser.[EN_BOM]*/ [Assemblies] WHERE [PartID] /*[Assembly_Part_ID]*/ = @source_part_id

    SELECT @max = COUNT(*) FROM @chkParts
    WHILE @cnt <= @max
    BEGIN
        SELECT @id = [id], @PID = [PID], @Plvl = [level] FROM @chkParts WHERE [id] = @cnt
        INSERT INTO @parts_list
            SELECT * FROM [fn_getParts](@PID, @Plvl)
        SET @cnt += 1
    END

    RETURN
END

这里是示例数据:

CREATE TABLE Assemblies (
  PartID int NOT NULL,
  Comp_PartID int NOT NULL
);
  
INSERT INTO Assemblies VALUES 
  (1, 2),  
  (1, 3),
  (1, 4),
  (1, 5),
  (1, 6),
  (3, 9),
  (3, 10),
  (10, 11),
  (10, 23),
  (10, 24),
  (10, 31),
  (11, 24),
  (11, 23);

最佳答案

以下生成的结果与您描述的逻辑相符,但与您期望的不同。也许你的逻辑需要调整一下?

declare @source_part_id int = 1, @level int = 0;

with cte (part, [level])
as (
  select @source_part_id part, @level [level]
  union all
  select Comp_PartID, [level]+1
  from Assemblies A
  inner join cte C on C.Part = A.PartID
)
select part, [level]
from cte
order by part, [level];

返回:

part    level
1       0
2       1
3       1
4       1
5       1
6       1
9       2
10      2
11      3
23      3
24      3
31      3
24      4
23      4

关于sql-server - 使用 CTE 代替表变量进行递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62785161/

相关文章:

java - 响应时间随着 Java 中并发性的增加而增加

mysql - 如何将数据从一个 SQL 列表复制到另一个 SQL 列表

sql-server - "Invalid column name"抛出到无法访问的脚本 block 内

sql - 检查生成脚本中的约束

Python - 二维列表的里程表样式组合

python - 避免 Python 的栈

sql - 在T-SQL的日期时间字段上使用类似LEAST的方法

sql-server - 如何使用具有托管标识的自动化帐户 Runbook 运行 Azure SQL Server 存储过程?

sql - 删除具有相同字段值的连续行

sql - T-SQL 按另一个表中的父键进行分组