【问题标题】:Repeat Rows N Times According to Column Value, Without Limit in Repeating根据列值重复行N次,重复次数不限
【发布时间】:2019-05-09 17:25:43
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复,但正如我之前提到的,您不能在 CTE 中使用此结构。
    【解决方案2】:

    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)
    

    我找到了解决方案:https://stackoverflow.com/a/7428903/4885037

    【讨论】:

    • 当你说不能在CTE结构中使用(MAXRECURSION 0)时我很困惑,你是什么意思?
    • 是的,我也很困惑。但是在 SQL Server 2014 中,我不能在 CTE 中使用 (MAXRECURSION 0),如上所述。
    • 我的解决方案是否在您的实例上运行?它都是独立的,所以应该运行..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    相关资源
    最近更新 更多