根据列值重复行N次,重复无限制

Repeat Rows N Times According to Column Value, Without Limit in Repeating

我在 SQL Server 2014 中有这样一个 table:

 IDSupply    Qty    PartName
 ---------------------------
 1          2        C
 2          4        B
 3          50000    A

我想根据带索引的 Qty 列重复每一行 N 次(例如 C 从 1 到 4 作为索引)

问题是什么:我为此目标使用了 2 个查询,但它们只重复了 100 次,如下所示:

WITH tally AS 
(
    SELECT 1 n
    UNION ALL
    SELECT n + 1 
    FROM tally 
)
SELECT partname, n.n Position
FROM supplylist t 
JOIN tally n ON n.n <= t.qty
ORDER BY partname, Position

和其他方法可以将每一行重复 32000 次,但我不能将其用作 CTE(因为 OPTION(MAXRECURSION 32500) CTE 问题)

 WITH Numbers(Num) AS
 (
     SELECT 1 AS Num

     UNION ALL 

     SELECT Num + 1
     FROM Numbers c
     WHERE c.Num < 30000
 )
 SELECT partname, qty, num
 FROM supplylist
 JOIN Numbers ON supplylist.qty >= Numbers.Num
 ORDER BY partname, num
 OPTION(MAXRECURSION 32500)

注意:我不能在 CTE 结构中使用上面的代码,如下所示:

 WITH Numbers(Num) AS
 (
     SELECT 1 AS Num

     UNION ALL 

     SELECT Num + 1
     FROM Numbers c
     WHERE c.Num < 30000
 ),
 CTE as
 (
     SELECT partname,qty, num
     FROM supplylist
     JOIN Numbers ON supplylist.qty >= Numbers.Num
     ORDER BY partname, num
     OPTION(MAXRECURSION 32500)
 )
 SELECT * 
 FROM CTE

请帮助我无限制地做到这一点,并且 CTE 结构没有问题。

您可以将最大递归设置为任何您想要的。尝试以下操作:

DECLARE @supplylist TABLE
(
IDSupply INTEGER,
Qty INTEGER,
PartName CHAR(1)
);

INSERT INTO @supplylist VALUES (1,2,'C'),(2,4,'B'),(3,50000,'C');

WITH Numbers(Num) AS
 (
   SELECT 1 AS Num
   UNION ALL 
   SELECT Num + 1
   FROM   Numbers c
   WHERE c.Num < 100000
 )


SELECT partname,qty, num
  FROM   @supplylist s
  INNER JOIN Numbers
        ON  Numbers.Num <= s.qty
  ORDER BY partname, num
  OPTION(MAXRECURSION 0);

Finlay 我找到了解决方案。我们不能在 CTE 结构中使用 "OPTION(MAXRECURSION 0)" 但我们可以将查询用作函数并在调用中使用 "OPTION(MAXRECURSION 0)" 和 运行 函数如下所示:

Create fnCreateIndex
(  
  @Pr1 Int
)
RETURNS TABLE 
AS
RETURN 
(
WITH Numbers(Num) AS
(
  SELECT 1 AS Num
  UNION ALL 
  SELECT Num + 1
  FROM Numbers c
  WHERE c.Num < @Pr1), 
CTE as
(
 SELECT partname, qty, num
 FROM supplylist
 JOIN Numbers ON supplylist.qty >= Numbers.Num
)
 Select * from cte
)

最后我们可以用它来获得结果:

 select * from fnCreateIndex (50000)  order by partname, num OPTION(MAXRECURSION 0)

我根据以下内容找到了解决方案: