Комбинации в SQL Server - PullRequest
       2

Комбинации в SQL Server

3 голосов
/ 14 апреля 2019

Используя 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

Еслих = 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

Спасибо

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Вы можете сделать это с помощью рекурсивного 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;

Здесь - это дБ <> скрипка.

Примечание: вам нужно представить результаты в виде строки, потому что SQL не позволяет вам возвращать переменное число столбцов. Вы можете поместить каждое значение в отдельный столбец, но тогда вы не сможете использовать переменную для управления размером комбинаций.

1 голос
/ 14 апреля 2019

Другой возможный подход заключается в использовании динамического 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...