Digamos que eu tenha uma mesa com um baralho numerado de 01 a 52. Eu poderia retornar os cartões superiores e inferiores, como se segurasse cada lado da consulta de seleção da união em minhas mãos esquerda e direita fazendo um:
select top 26 * from DeckOfCards order by CardNumber desc
union all
select top 26 * from DeckOfCards order by CardNumber asc
Seria uma divisão equilibrada.
Mas como eu poderia fazer com que o SQL Server entrelaçasse os resultados retornados, como se eu tivesse pegado as duas partes dessa união, uma metade na mão esquerda e a outra na direita, e as embaralhasse uma vez como um baralho?
Ou seja: CardNumber 52, seguido de 1, na seguinte sequência: 52, 1, 51, 2, 50, 3, 49, 4, etc...
Esta não é uma questão de lição de casa, apenas uma daquelas coisas que passam pela minha cabeça quando tento fechar os olhos. :)
Eu queria fornecer uma solução alternativa (usando os dados de amostra na resposta de Serpiton - obrigado!) Que evita classificações. Isso deveria ser possível usando
ROW_NUMBER
, mas o otimizador de consulta atualmente não reconhece sua projeção como exclusiva. Então:SQLFiddleName
Resultado:
Planos de execução:
Um pouco de matemática pode ajudar a conseguir isso
CAST(CardNumber / 27 as bit)
retorna 0 para o número do cartão abaixo de 27 e 1 para o número acima de 26, usando isso é possível criar uma ordem diferente para os dois blocos diferentes:(1 - CAST(CardNumber / 27 as bit)) * (CardNumber* 2)
coloque o primeiro cartão 26 na posição par, pois o primeiro membro será 1 para esse cartão e 0 para o outro(CAST(CardNumber/ 27 as bit)) * (1 + (52 - CardNumber) * 2)
irácolocar a segunda carta 26 na posição ímpar, por exemplo(1 + (52 - CardNumber) * 2)
iráretornar os valores ímpares em ordem decrescenteSQLFiddle examplecom a fórmula de ordem como uma segunda coluna para ver como funciona
A chave é ter um
ORDER BY
que possa trabalhar com os dados de ambos os conjuntos. Eu costumavaROW_NUMBER
obter uma solução um pouco mais geral, mas seria possível evitar as classificações fazendo matemática direta nos números dos cartões.