none
Ordenação em campo NVARCHAR RRS feed

  • Pergunta

  • Amigos,

     

    Em uma aplicação que estou fazendo uma manutenção, eu necessito ordenar uma consulta. Existe uma tabela no banco que possui um campo NVARCHAR e é justamente esse campo que tenho que ordernar, só que o campo possui valores númericos e alguns com letras.

     

    Exemplo: 10005, 1001, 10005A, 10005D, 1001A etc...

     

    Se eu simplesmente ordenar os valores 1000? aparecem em cima dos valores 100? por ser string.

     

    Alguem poderia me ajudar como faço para ordenar esse campo crescentemente?

    terça-feira, 8 de janeiro de 2008 16:22

Todas as Respostas

  •  

    Olá!!!

     

    Se existe um padrão, por exemplo, não tem letra antes do quarto caractér, poderia recortar a string, converter para int e então ordernar por esse resultado. Exemplo:

     

    SELECT...

    FROM...

    ORDER BY CONVERT (INT, LEFT (Campo, 4))

     

     

    MAS, tem que ter certeza que não vai ter caractéres naquela faixa que está sendo recortada.

     

     

     

    Abraço!!!

    terça-feira, 8 de janeiro de 2008 16:28
  •  

    Invelizmente vc. vai ter que usar um padrao, vc. pode usar um relapce por fabela para trocar o valor da letra por nada e depois converter para inteiro seque exemplo:

     

     


     Create Table #Exemplo (campo varchar(10))

     insert into #Exemplo (campo) Values ('1000')
     insert into #Exemplo (campo) Values ('1002')
     insert into #Exemplo (campo) Values ('1003')
     insert into #Exemplo (campo) Values ('104A')
     insert into #Exemplo (campo) Values ('104Z')
     insert into #Exemplo (campo) Values ('102C')


    Select * from #Exemplo Order by case when isnumeric(campo) = 1 then convert(int,campo) Else 0 End

    -- ou

    Select * from #Exemplo Order by case when isnumeric(campo) = 1 then convert(int,campo)
                                    Else convert(int,Substring(Campo,1,len(campo)-1)) End

     

     

     

    Abs;

    terça-feira, 8 de janeiro de 2008 16:29
  •  

    Eles são com 4 ou 5 números podendo der seguidos de uma letra ou não.

     

    Exemplo: 1001, 1001C, 15236, 15236J

    terça-feira, 8 de janeiro de 2008 16:48
  • acho que meu segundo select pode ajudar, neste caso.

     

    Abs;

     

     

     

    terça-feira, 8 de janeiro de 2008 16:49
  • Boa Tarde,

     

    Você pode criar uma função para realizar essa ordenação. Segue um exemplo:

     

    Code Block

    CREATE FUNCTION dbo.ConverteStringFNum(@str VARCHAR(20))

    RETURNS SMALLINT

    AS

    BEGIN

     

    DECLARE @strIntermediario VARCHAR(20), @iterador SMALLINT

    SET @iterador = 1

    SET @strIntermediario = '0'

     

    WHILE @iterador <= LEN(@str) AND ISNUMERIC(@strIntermediario) = 1

    BEGIN

    SET @strIntermediario = @strIntermediario + SUBSTRING(@str,@iterador,1)

    SET @iterador = @iterador + 1

    END

     

    SET @strIntermediario = LEFT(@strIntermediario,LEN(@strIntermediario)-1)

     

    DECLARE @retorno SMALLINT

    SET @retorno = CAST(@strIntermediario AS SMALLINT)

    RETURN (@retorno)

    END

     

    CREATE TABLE #tblRegistros (CODIGO VARCHAR(20))

    INSERT INTO #tblRegistros VALUES ('0123sda')

    INSERT INTO #tblRegistros VALUES ('012sda')

    INSERT INTO #tblRegistros VALUES ('1sda')

     

    SELECT CODIGO FROM #tblRegistros ORDER BY CODIGO

    SELECT CODIGO FROM #tblRegistros ORDER BY dbo.ConverteStringFNum(CODIGO)

     

    DROP TABLE #tblRegistros

     

     

    No entanto, é necessário que sua consulta retorne poucos registros. Utilizar essa function para ordenação de muitos registros poderá levar a problemas de desempenho.

     

    [ ]s,

     

    Gustavo

    terça-feira, 8 de janeiro de 2008 16:50
  • Napoleão,

     

    Os exemplos dos colegas com certeza vão te ajudar em muito.

     

    Mas particularmente você já pensou em criar nesta sua table um campo do tipo Int com o propriedade Identity(1,1), e fazer a organização através deste campo, será que isso não ficaria melhor se levarmos em consideração a quantidade de registros com certeza o tempo de processamento seria menor e consequentemente o tempo de resposta menor ainda.

     

    Amigos o você acham desta idéia?

    terça-feira, 8 de janeiro de 2008 17:05
  •  

    outra maneira

     


    drop table #Exemplo
     Create Table #Exemplo (campo varchar(10))

     insert into #Exemplo (campo) Values ('1000')
     insert into #Exemplo (campo) Values ('1002')
     insert into #Exemplo (campo) Values ('1003')
     insert into #Exemplo (campo) Values ('104A')
     insert into #Exemplo (campo) Values ('104Z')
     insert into #Exemplo (campo) Values ('102C')
     insert into #Exemplo (campo) Values ('40CC')
     insert into #Exemplo (campo) Values ('5AA')
     insert into #Exemplo (campo) Values ('6BB')

     

    -- mesmo exemplo do gustavo mais pensando de outra forma.


     Select *
     From #Exemplo
     order by convert(int, Case When Isnumeric(campo) = 1then campo
     Else Left(campo,PATINDEX('%[^0-9]%' , upper(campo))-1) end)


     

     

    Abs;

    terça-feira, 8 de janeiro de 2008 17:06
  • Boa Tarde,

     

    Está ficando difícil de superar o Colla em alguns posts já que embora meus exemplos todos funcionem, ele sempre aparece com uma solução TSQL menor do que a minha (rs). Boa saída com o PatIndex e a regular Expression.

     

    Sobre a colocação do Júnior, se o campo alfanumérico tiver um forte significado negocial e (ou) seja atribuído com uma outra lógica diferente do Identity, não será possível trabalhar com o Identity. Do contrário, se a idéia é realmente gerar um identificar único e os caractéres textuais puderem ficar em outro campo, certamente a sugestão é bem válida. Teremos todos os benefícios citados.

     

    [ ]s,

     

    Gustavo

    terça-feira, 8 de janeiro de 2008 17:12
  • o que eu faco quando preciso algo assim e criar um campo calculado que receba a logica aplicada, assim a ordenacao pode ser feita pelo campo calculado ( inclusive podemos criar indices para esse tipo de campo quando ele for regular )

     

    Show de bola esse esquema de varias solucoes, isso so faz alumentar a qualidade das respostas e mostrar o quao forte e o TSQL,

     

    Abraco a todos.

     

     

     

    terça-feira, 8 de janeiro de 2008 17:18
  • Gustavo,

     

    Vai se acostumando o homem é ferra!!!

     

    Estou a mais de 2 anos todos os dias nos fórums MSDN e TechNet de SQL Server, e fico sempre surpreso com as respostas do Marcelo, isso é muito bom todos nós, sempre temos um profissional como ponto de referência.

     

    Hoje pessoalmente posso dizer que o Marcelo Colla, Nilton Pinheiro e Alexandre VM são as referência.

     

    Valeu, vivendo e aprendendo vamos juntos a cada enriquecer o nosso conhecimento.

     

    Nos últimos dias estou muito atarefado, não estou tendo tanto tempo para o fórum, mas sempre que possível estou aqui dedicando um pouco do meu tempo.

     

    Mas acredito que nos próximos dias já estarei com força total!!!

    terça-feira, 8 de janeiro de 2008 17:28
  • Deleted
    sexta-feira, 23 de agosto de 2019 15:00