根据列值重复行N次,重复次数不受限制

时间:2018-12-07 23:39:06

标签: sql-server tsql sql-server-2014

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

 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(因为CTE的OPTION(MAXRECURSION 32500)问题)

 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结构没有问题。

2 个答案:

答案 0 :(得分:2)

您可以将最大递归设置为任意值。请尝试以下操作:

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);

答案 1 :(得分:0)

Finlay我找到了解决方案。我们不能在CTE结构中使用“ OPTION(MAXRECURSION 0)”,但可以将查询用作函数,并在调用和运行Function中使用“ 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)

我根据https://stackoverflow.com/a/7428903/4885037

找到了解决方案