без динамического sql?
Тогда это возможно, если вы не возражаете, что sql возвращает фиксированное количество столбцов.
Даже без использования PIVOT.
Пример с 4 числовыми столбцами, но с более низким @MaxLvl
Тест на rextester здесь
DECLARE @SC TABLE ([Groups] CHAR(2) PRIMARY KEY);
INSERT INTO @SC ([Groups]) VALUES
('AB'),('AC'),('AD'),('BC'),('BD'),('CD');
DECLARE @MaxLvl INT = 3;
;WITH CTE AS
(
SELECT Groups AS Base, 1 Lvl,
CAST (Groups AS VARCHAR(MAX)) AS ListGroups,
Groups AS [1],
charnull AS [2],
charnull AS [3],
charnull AS [4]
FROM @SC
CROSS APPLY (SELECT CAST(NULL AS CHAR(2)) AS charnull) ch
UNION ALL
SELECT c.Base, c.Lvl+1, c.ListGroups+','+t.Groups,
c.[1],
IIF(c.Lvl = 1, t.Groups, c.[2]),
IIF(c.Lvl = 2, t.Groups, c.[3]),
IIF(c.Lvl = 3, t.Groups, c.[4])
FROM CTE AS c
JOIN @SC AS t ON c.Lvl < @MaxLvl
)
SELECT
ROW_NUMBER() OVER (ORDER BY ListGroups) AS rn,
[1],[2],[3],[4]
FROM CTE
WHERE Lvl = @MaxLvl
ORDER BY ListGroups;
Но если бы Dynamic Sql был бы вариантом?
Вот пример:
-- Using a temporary table for demonstration
IF OBJECT_ID('tempdb..#SC') IS NOT NULL DROP TABLE #SC;
CREATE TABLE #SC ([Groups] CHAR(2) PRIMARY KEY);
INSERT INTO #SC ([Groups]) VALUES
('AB'),('AC'),('AD'),('BC'),('BD'),('CD');
DECLARE @MaxLvl INT = 3;
DECLARE @DynamicSql VARCHAR(max);
DECLARE @Fields VARCHAR(max) = 'SC1.[Groups]';
DECLARE @AliasedFields VARCHAR(max) = 'SC1.[Groups] AS [1]';
DECLARE @Joins VARCHAR(max) = 'FROM #SC AS SC1';
DECLARE @Lvl INT = 1;
WHILE @Lvl < @MaxLvl
BEGIN
SET @Lvl = @Lvl + 1;
SET @Fields = CONCAT(@Fields,', ','SC',@Lvl,'.[Groups]');
SET @AliasedFields = CONCAT(@AliasedFields,',',CHAR(10),'SC',@Lvl,'.[Groups] AS [',@Lvl,']');
SET @Joins = CONCAT(@Joins,CHAR(10),'CROSS JOIN #SC AS SC', @Lvl);
END;
SET @DynamicSql = CONCAT('SELECT ',
CHAR(10), 'ROW_NUMBER() OVER (ORDER BY ', @Fields, ') AS RN,',
CHAR(10), @AliasedFields ,
CHAR(10), @Joins,
CHAR(10), 'ORDER BY ', @Fields);
-- select @DynamicSql AS DynamicSql;
EXEC(@DynamicSql);
Тест на rextester здесь