Eu preciso de uma consulta que pode ser usada em (ou como) uma função e recupera todas as combinações de n valores. E eu preciso de todas as combinações de comprimento k onde k = 1..n.
Entrada e resultado de amostra estendida para que a entrada tenha 3 valores em vez de 2 - no entanto, o número de valores de entrada pode variar de 1 a n.
Exemplo: Entrada: tabela com valores em uma coluna em várias linhas
Value (nvarchar(500))
------
Ann
John
Mark
Saída#1: tabela com valores concatenados em uma coluna
Ann
John
Mark
Ann,John
John,Mark
Ann,Mark
Ann,John,Mark
Para valores relativamente pequenos de
n
(20 neste exemplo), você pode usar um método que explora o fato de que os inteiros naturais são combinações de bits.Solução T-SQL
Dados de amostra:
Solução:
Amostra de saída:
Plano de execução:
Leva 41 segundos para gravar as 1.048.576 combinações em uma variável no meu laptop. Com o paralelismo forçado, consegui diminuir o tempo de execução
DOP 8
para 13 segundos.Se você precisar de uma tabela Numbers, esta é uma maneira rápida de produzir uma:
Solução SQLCLR
Uma implementação muito mais eficiente é possível no SQLCLR (SQL Server 2005 em diante):
Exemplo de uso:
Resultado:
Usando o conjunto de 20 elementos de antes:
Solução SQLCLR:
O tempo de execução é de 2,5 segundos para as 1.048.576 combinações no meu laptop em
DOP 1
.Criando a entrada CSV:
Encontrando as combinações:
Código fonte C#: