Tsql 有一个数字序列,创建一个金字塔

Tsql 有一个数字序列,创建一个金字塔,tsql,sql-server-2012,Tsql,Sql Server 2012,是否可能有一系列数字,例如: 1,2,3,4,5 要创建/打印类似金字塔的形状,请执行以下操作: 一, 1, 2 1, 2, 3 1, 2, 3, 4 1,2,3,4,5 使用循环可以很容易地做到这一点,但是我希望避免它们 到目前为止,我的解决方案是动态创建每一行的select字符串,并将所有行合并以获得所需的结果。例如: -- @Line1 = '1, select @Line1 = coalesce(@Line1 + ',', '') + Num from Numbers wher

是否可能有一系列数字,例如:

1,2,3,4,5

要创建/打印类似金字塔的形状,请执行以下操作:

一, 1, 2 1, 2, 3 1, 2, 3, 4 1,2,3,4,5

使用循环可以很容易地做到这一点,但是我希望避免它们

到目前为止,我的解决方案是动态创建每一行的select字符串,并将所有行合并以获得所需的结果。例如:

-- @Line1 = '1, 
select @Line1 = coalesce(@Line1 + ',', '') + Num 
  from Numbers
 where Num < 2

-- @Line2 = '1, 2,'
select @Line2 = coalesce(@Line2 + ',', '') + Num 
  from Numbers
 where Num < 3

select @Line1
union
select @Line2
.
.
.
然后执行它。代码不完整,但我认为它给出了我正在尝试的想法

有什么改进的办法吗

相关的:

注意:这可能没有实际用途。我发现这是一个用各种语言进行的练习,并且都在循环中提出了一个解决方案。我认为在SQL Server中尝试它会很有趣。

试试这个

WITH Numbers AS 
(
    SELECT TOP 5 
           ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nr 
    FROM master..spt_values
) 
SELECT STUFF(
            (
            SELECT ',' + CAST(x.Nr AS VARCHAR(10)) 
            FROM Numbers AS x 
            WHERE x.Nr<=Numbers.Nr
            FOR XML PATH('')
            ),1,1,''
            ) AS Result
FROM Numbers
试试这个

WITH Numbers AS 
(
    SELECT TOP 5 
           ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nr 
    FROM master..spt_values
) 
SELECT STUFF(
            (
            SELECT ',' + CAST(x.Nr AS VARCHAR(10)) 
            FROM Numbers AS x 
            WHERE x.Nr<=Numbers.Nr
            FOR XML PATH('')
            ),1,1,''
            ) AS Result
FROM Numbers

如果您有:

A,即包含从1到某个大数字和 一个聚合函数,可以。这样的函数STRING_AGG将添加到SQL Server的下一个版本中,即2016年之后的版本中。有多种技术可以创建这样的函数。链接文章展示了各种选项,使用SQLCLR、XML操作符、CTE、游标等。fastes方法是SQLCLR。 假设连接方法为GROUP_CONCAT,则可以编写:

select o.n,dbo.GROUP_CONCAT_S(x.n) as Result
from numbers  o outer apply (select n from numbers i where i.n<=o.n) x
where o.n<=5
group by o.n

如果您有:

A,即包含从1到某个大数字和 一个聚合函数,可以。这样的函数STRING_AGG将添加到SQL Server的下一个版本中,即2016年之后的版本中。有多种技术可以创建这样的函数。链接文章展示了各种选项,使用SQLCLR、XML操作符、CTE、游标等。fastes方法是SQLCLR。 假设连接方法为GROUP_CONCAT,则可以编写:

select o.n,dbo.GROUP_CONCAT_S(x.n) as Result
from numbers  o outer apply (select n from numbers i where i.n<=o.n) x
where o.n<=5
group by o.n

我将此作为第二个答案,因为这是一种完全不同的方法:

递归CTE只是一个隐藏的RBAR,因此是一个不可见的循环。但它——嗯——更漂亮:-

WITH recCTE AS
(
    SELECT 1 AS Nr, CAST('1' AS VARCHAR(MAX)) AS concString
    UNION ALL 
    SELECT recCTE.Nr+1,concString + ',' + CAST(recCTE.Nr+1 AS VARCHAR(10))
    FROM recCTE
)
SELECT TOP 5 * FROM recCTE

我将此作为第二个答案,因为这是一种完全不同的方法:

递归CTE只是一个隐藏的RBAR,因此是一个不可见的循环。但它——嗯——更漂亮:-

WITH recCTE AS
(
    SELECT 1 AS Nr, CAST('1' AS VARCHAR(MAX)) AS concString
    UNION ALL 
    SELECT recCTE.Nr+1,concString + ',' + CAST(recCTE.Nr+1 AS VARCHAR(10))
    FROM recCTE
)
SELECT TOP 5 * FROM recCTE

为什么是T-SQL而不是编程语言?@H.Pauwelyn我认为尝试不同于循环的东西会很有趣。tsql也是我每天使用的一种语言,我想试试我的技能。如果你有一个数字表,你可以执行一个外部应用程序来获取eash之前的所有数字。在那之后,您需要一些方法来连接字符串,使用T-SQL而不是编程语言?@H.Pauwelyn我认为尝试不同于循环的东西会很有趣。tsql也是我每天使用的一种语言,我想试试我的技能。如果你有一个数字表,你可以执行一个外部应用程序来获取eash之前的所有数字。在此之后,您需要某种方法来连接字符串*有趣的是,您可以使用它的上限是2508。@RaduGheorghiu这是由于master::spt_values中的值。。。您可以使用实时计数表,或者只需将交叉连接master::spt_值添加为x,以获得更大的数字。。。目标字符串的大小也很重要,当然……啊,当然。没有想到要从主..spt_值中进行选择。很棒的东西@Shnugo*有趣的是,您可以使用它的上限是2508。@RaduGheorghiu这是由于master::spt_values中的值。。。您可以使用实时计数表,或者只需将交叉连接master::spt_值添加为x,以获得更大的数字。。。目标字符串的大小也很重要,当然……啊,当然。没有想到要从主..spt_值中进行选择。很棒的东西@Shnugo!我想这里还有一个问题,对于“selecttop102*fromreccte”,我最终得到了语句终止的错误。在语句完成之前,已用尽最大递归100。。无论如何,“递归CTE”是一个有趣的解决方案@Athafoud谷歌公式maxrecursionYeap!我已经这么做了!我只是在测试不同的场景,看看有什么限制。我想这里也有一个litim,对于“select top 102*from recCTE”,我最终得到了语句终止的错误。在语句完成之前,已用尽最大递归100。。无论如何,“递归CTE”是一个有趣的解决方案@Athafoud谷歌公式maxrecursionYeap!我已经这么做了!我只是在测试不同的场景,看看有什么限制。这三个答案都很好。出于偏爱,我接受了这个。IMHO更简洁易读。将这些数字作为输入,可以减少对特定问题的限制。唯一的缺点是我必须创建groupconcat函数。这三个答案都很好。出于偏爱,我接受了这个。IMHO更简洁易读。将这些数字作为输入,可以减少对特定问题的限制。唯一的缺点是我必须创建组_ S函数。