I have a dataset that looks like this
Position | Value |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 8 |
3 | 5 |
3 | 6 |
And I’d like to generate all combinations of strings with the value at each position.
For this example, the output would look like
Output |
---|
185 |
285 |
385 |
186 |
286 |
386 |
The order doesn’t particularly matter.
Note: There can be an arbitrary amount of groups and values per group.
The below SQL sets up the sample input.
x
Declare @Table Table
(
groupId int,
value int
)
Insert Into @Table
Select 1,1
union select 1,2
union select 1,3
union select 2,8
union select 3,5
union select 3,6
Select
*
From
@Table
Advertisement
Answer
You can use a recursive CTE for this, dynamic SQL is not needed
WITH cte AS (
SELECT
1 AS Position,
CAST(Value AS varchar(100)) AS Value
FROM #YourTable t
WHERE Position = 1
UNION ALL
SELECT
cte.Position + 1,
CAST(cte.Value + t.Value AS varchar(100))
FROM #YourTable t
JOIN cte ON cte.Position + 1 = t.Position
)
SELECT *
FROM cte
WHERE cte.Position = (SELECT TOP 1 t2.Position FROM #YourTable t2 ORDER BY t2.Position DESC);
If there are gaps then you a need a more complex solution:
CREATE FUNCTION dbo.GetNextValues (@gtThanPosition int)
RETURNS TABLE AS RETURN
SELECT TOP (1) WITH TIES
t.Position,
t.Value
FROM YourTable t
WHERE t.Position > @gtThanPosition OR @gtThanPosition IS NULL
ORDER BY t.Position;
GO
WITH cte AS (
SELECT
t.Position,
CAST(Value AS varchar(100)) AS Value
FROM dbo.GetNextValues(NULL) t
UNION ALL
SELECT
t.Position,
CAST(cte.Value + t.Value AS varchar(100)) AS Value
FROM cte
CROSS APPLY dbo.GetNextValues(cte.Position) t
)
SELECT Value
FROM cte
WHERE cte.Position = (SELECT TOP 1 t2.Position FROM YourTable t2 ORDER BY t2.Position DESC);