SQL Server中的组合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server中的组合相关的知识,希望对你有一定的参考价值。

使用SQL Server(2008)并给出一个包含行的表,如下所示:

Id
--
4
7

使用x的值(例如参数@x),我希望能够生成x列的行,给出表中Id值的所有组合:

例如,对于x = 2,将产生具有两列的输出,如下所示:

4,4
4,7
7,4
7,7

在x = 3的情况下,结果将是具有三列的行,如下所示:

4,4,4
4,4,7
4,7,4
4,7,7
7,4,4
7,4,7
7,7,4
7,7,7

该表可能包含比上例中的2行更多或更少的行,这也取决于x的值将改变输出中的组合行/列的数量。

例如。如果表包含:

4
7
9

如果x = 2,就会产生

4,4
4,7
4,9
7,4
7,7
7,9
9,4
9,7
9,9

如果x = 3,就会产生

4,4,4
4,4,7
4,4,9
4,7,4
4,7,7
4,7,9
4,9,4
4,9,7
4,9,9
etc

谢谢

答案

您可以使用递归CTE执行此操作:

with cte as (
      select convert(varchar(max), id) as ids, 1 as cnt
      from t
      union all
      select ids + ',' + convert(varchar(max), id), cnt + 1
      from cte join
           t
           on cte.cnt < @x
     )
select *
from cte
where cnt = @x;

Here是一个db <>小提琴。

注意:您需要将结果表示为字符串,因为SQL不允许您返回可变数量的列。您可以将每个值放在单独的列中,但是您将无法使用变量来控制组合的大小。

另一答案

另一种可能的方法是使用动态SQL:

-- Table
CREATE TABLE #Numbers (
   Id int
)
INSERT INTO #Numbers
   (Id)
VALUES
   (4),
   (7),
   (9)

-- Declarations
DECLARE @select nvarchar(max)
DECLARE @from nvarchar(max)
DECLARE @stm nvarchar(max)
DECLARE @x int

-- Numbers
SELECT @x = 2

-- Statement generation 
;WITH CounterCTE as (
   SELECT 1 AS Counter
   UNION ALL
   SELECT Counter + 1   
   FROM CounterCTE
   WHERE Counter < @x
)
SELECT 
   @select = (SELECT CONCAT(N',t', Counter, N'.Id') FROM CounterCTE FOR XML PATH('')),
   @from = (SELECT CONCAT(N',#Numbers t', Counter) FROM CounterCTE FOR XML PATH(''))
SET @stm = CONCAT(
   N'SELECT ', 
   STUFF(@select, 1, 1, N''),
   N' FROM ',
   STUFF(@from, 1, 1, N'')
)   

-- Execution
PRINT @stm
EXEC sp_executesql @stm

@x = 2的输出

Id  Id
4   4
7   4
9   4
4   7
7   7
9   7
4   9
7   9
9   9

以上是关于SQL Server中的组合的主要内容,如果未能解决你的问题,请参考以下文章

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

SQL Server中的组合

选择不在其他表sql server中的字段组合

组合查询时的 SQL-server 语法错误(传递查询)

SQL Server 2016 存储过程中的串联 OPENJSON

SQL SERVER 批量生成编号