Domanda

Ho dati misti nella colonna nvarchar (parole e numeri). Qual è il modo più veloce per ordinare i dati in questa colonna in Ordine numerico

Esempio di risultato:

  • 1
  • 2
  • 3
  • ...
  • 10
  • 11
  • ...
  • aaaa
  • aaab
  • b
  • ba
  • ba
  • ...
È stato utile?

Soluzione

Usa questo:

ORDER BY
    CASE WHEN ISNUMERIC(column) = 1 THEN 0 ELSE 1 END,
    CASE WHEN ISNUMERIC(column) = 1 THEN CAST(column AS INT) ELSE 0 END,
    column

Funziona come previsto.


Nota : dici il modo più veloce . Questo sql è stato veloce per me da produrre, ma il piano di esecuzione mostra una scansione della tabella, seguita da un calcolo scalare. Questo potrebbe eventualmente produrre un risultato temporaneo contenente tutti i valori di quella colonna con alcune colonne temporanee extra per i risultati ISNUMERIC. Potrebbe non essere veloce da eseguire.

Altri suggerimenti

Se lasci il pad dei tuoi numeri con 0 e li ordini, otterrai i risultati desiderati. Dovrai assicurarti che il numero di 0 con cui riempi corrisponda alla dimensione della colonna varchar.

Dai un'occhiata a questo esempio ...

Declare @Temp Table(Data VarChar(20))

Insert Into @Temp Values('1')
Insert Into @Temp Values('2')
Insert Into @Temp Values('3')
Insert Into @Temp Values('10')
Insert Into @Temp Values('11')
Insert Into @Temp Values('aaaa')
Insert Into @Temp Values('aaab')
Insert Into @Temp Values('b')
Insert Into @Temp Values('ba')
Insert Into @Temp Values('ba')

Select * From @Temp
Order By Case When IsNumeric(Data) = 1 
              Then Right('0000000000000000000' + Data, 20) 
              Else Data End

Si noti inoltre che quando si utilizza un'istruzione case è importante che ogni ramo dell'istruzione case restituisca lo stesso tipo di dati, altrimenti si otterranno risultati errati o un errore.

--controlla l'esistenza
se esiste (selezionare * da dbo.sysobjects dove [id] = object_id (N'dbo.t ') E proprietà dell'oggetto (id, N'IsUserTable') = 1)
    drop table dbo.t
Vai

- crea una tabella di esempio
crea una tabella dbo.t (c varchar (10) non null)
imposta nocount su

--popola la tabella di esempio
inserire in dbo.t (c) valori ('1')
inserire in dbo.t (c) valori ('2')
inserire in dbo.t (c) valori ('3')
inserire in dbo.t (c) valori ('10 ')
inserire in dbo.t (c) valori ('11')
inserire in valori dbo.t (c) ('aaaa')
inserire in dbo.t (c) valori ('aaab')
inserire in dbo.t (c) valori ('b')
inserire in dbo.t (c) valori ('ba')
inserire in dbo.t (c) valori ('ba')

- restituisce i dati
seleziona c da dbo.t
ordina per caso quando isnumeric (c) = 1 then 0 else 1 end,
case when isnumeric (c) = 1 then cast (c as int) else 0 end,
c

Puoi trattare i dati come alfanumerici o numerici, non entrambi contemporaneamente. Non penso che ciò che stai cercando di fare sia possibile, il modello di dati non è impostato in modo appropriato.

  

Non penso a cosa stai cercando di fare   è possibile

Questo esempio funziona bene

SELECT * FROM TableName
ORDER BY CASE WHEN 1 = IsNumeric(ColumnName) THEN Cast(ColumnName AS INT) END

Il risultato è:

  • a
  • b
  • c
  • ...
  • 1
  • 2
  • 3

Ma prima ho bisogno dei numeri.

Questo dovrebbe funzionare:

select * from Table order by ascii(Column)

Lancialo.

SELECT * FROM foo ORDER BY CAST(somecolumn AS int);

È passato un po 'di tempo da quando ho toccato SQL Server, quindi la mia sintassi potrebbe essere del tutto errata :) :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top