Então, estou trabalhando em um quebra-cabeça de golfe de código e preciso adicionar uma coluna "número" INT n a um resultado, mantendo a ordem atual.
Digamos que meus dados de origem sejam:
SELECT value
FROM STRING_SPLIT('one,two,three,four,five', ',')
que retorna os itens na ordem original (desejada):
value
-----
one
two
three
four
five
Se eu tentar usar ROW_NUMBER()
ou RANK()
for forçado a especificar um ORDER BY
, para o qual value
é a única opção legal:
SELECT value, n = ROW_NUMBER() OVER(ORDER BY value)
FROM STRING_SPLIT('one,two,three,four,five',',')
Mas isso (como esperado) classifica value
em ordem alfabética em vez de deixá-lo na ordem original desejada:
value n
------ ---
five 1
four 2
one 3
three 4
two 5
A junção a uma tabela numérica não funciona, pois sem uma WHERE
cláusula obterei uma junção externa completa.
O melhor que consegui foi usar uma tabela temporária com um campo de identidade:
CREATE TABLE #argg (n INT IDENTITY(1,1), v VARCHAR(99))
INSERT #argg
SELECT value v
FROM STRING_SPLIT('one,two,three,four,five',',')
SELECT *
FROM #argg
DROP TABLE #argg
mas isso é muito longo e irritante. Alguma ideia melhor?
A maneira canônica de fazer isso é a seguinte:
ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
. Se você está jogando golfe, você pode tentar algo assim:Funciona para o caso simples que você postou na pergunta:
Devo dizer que não há uma garantia documentada de que o
ROW_NUMBER()
valor estará na ordem exata que você espera. Mas é golfe de código, então isso parece bom o suficiente.Você não pode confiar no seu
INSERT
para gerarIDENTITY
valores na ordem de sua string original. Isso pode ser o que você observa, mas isso é apenas uma coincidência de sorte e certamente não é garantido.O seguinte funcionará se você não tiver duplicatas:
Para código de golfe talvez:
Se você tiver duplicatas, torna-se muito mais complexo. Algumas ideias aqui talvez:
Outra opção é usar uma sequência:
Resultado:
É irritante que
STRING_SPLIT
foi implementado sem uma opção de numeração embutida. Vote na mudança em https://feedback.azure.com/forums/908035-sql-server/suggestions/32902852-string-split-is-not-feature-completeApenas adicionando mais uma alternativa da sua pergunta. Mas acho que o pedido não é garantido,