2012-03-26 7 views
8

Domyślnie SQL porządkuje liczby przed znakami.ORDER BY varchar z [a-9] zamiast [0-Z] w SQL

Więc jeśli mam kolumny "name":

abc 
ab1 
a1b 
1ba 
1bac 
b21 

Od rodzaju SQL przez 0-Z (pierwszy od 0 do 9, a następnie AZ), zapytanie

SELECT * FROM ... ORDER BY name 

spowoduje :

1ba 
1bac 
a1b 
ab1 
abc 
abc1 
b21 

Ale chcę, aby posortować według a-0 (pierwszy AZ, następnie 0-9).

abc 
abc1 
ab1 
a1b 
b21 
1ba 
1bac 

Jak zrobić to w zapytaniu? Dokładniej, jak mam to zrobić w SQLite?

Znalazłem jedno rozwiązanie w Sort MySQL results alphabetically, but with numbers last, ale tylko dla pierwszego znaku.

+0

Czy Twoje wartości mają zawsze 3 znaki? – gbn

+0

Można [użyć interfejsu C do utworzenia funkcji] (http://www.sqlite.org/c3ref/create_function.html), który używa ['regexp'] (http://sqlite.org/lang_expr.html) operator, aby wyrzucić litery i cyfry w oddzielnych kolumnach. –

+0

@ gbn Nie, mogą bardzo długo. Prawdopodobnie powinienem to pokazać :) – Nic

Odpowiedz

0

To jest mój pomysł: dodasz kolejny „help_column”, który sprawdza, czy pierwszy char jest liczbą i przypisać 1 do niego, inaczej przypisać 0, a następnie kolejność według tej kolumny, a następnie według nazwy:

select *, case 
      when substring(name,1,1) like '[0-9]' then 1 
      else 0 
      end as help_order 
from (
select 'ab1' as name union select 'a1b' as name union select '1ba' as name union select 'b21' as name 
) a 
order by help_order, name 

Oczywiście, może być konieczne poprawienie wyrażenia regularnego [0-9] w celu leczenia więcej niż jednego numeru, jeśli to konieczne.

I, oczywiście, należy zastąpić zapytanie wewnętrzne (tym z kilkoma związkami z tabelą).

+0

To będzie działać tylko dla pierwszej postaci (popełniłem ten sam błąd przy pierwszej próbie) –

1

testu z tych danych proszę

declare @t table(a char(3)) 
insert @t values('ab1') 
insert @t values('a1b') 
insert @t values('1ba') 
insert @t values('b21') 
insert @t values('12a') 
insert @t values('13b') 


select a, 
patindex('[0-9]%', a + 'a'), 
patindex('_[0-9]%', a + 'a'), 
patindex('__[0-9]%', a + 'a') 
from @t order by 2, 3, 4, 1 

lub

select a 
from 
(select a, 
patindex('[0-9]%', a + 'a') b, 
patindex('_[0-9]%', a + 'a') c, 
patindex('__[0-9]%', a + 'a') d 
from @t) e 
order by b, c, d, a 
+4

Nie wierzę, że to jest poprawna SQLite składnia. –

3

Proponuję SELECT ing inną kolumnę, powiedzmy name_replace z cyfr zastąpionych przez postać wysokiej ASCII (takich jak ~) , a następnie sortowanie na tej kolumnie, a następnie na nazwę. Niestety SQLite nie posiada wsparcie dla regular expression wymienić:

SELECT name, replace(... replace(replace(name, '0', '~'), '1', '~') ... '9', '~') AS name_replace 
    FROM mytable 
ORDER BY name_replace, name 

Cyfry przyjdzie ostatni podczas sortowania na name_replace. Sortowanie na numer name zostanie następnie uporządkowane według cyfr.

0

Thsi zastępuje od 0 do 9 ASCII 122 (co oznacza małe litery z).

SQLLite nie posiada funkcji CHAR zrobić zastąpienie przez kod znaku (np CHAR(123) do CHAR(132)), które mogą być potrzebne, zamiast mojego CHAR (123) próbować

Nietestowane oczywiście :-)

ORDER BY 
    REPLACE 
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(name, '0', '{0') 
    , '1', '{2') 
    , '2', '{2') 
    , '3', '{3') 
    , '4', '{4') 
    , '5', '{5') 
    , '6', '{6') 
    , '7', '{7') 
    , '8', '{8') 
    , '9', '{9') 

Edit: chociaż rozwiązanie @David Faber robi to samo, ale nieco prostsze ...

2

To załatwia sprawę z dostarczonych danych.

SELECT * 
FROM Table 
ORDER BY Name COLLATE SQL_EBCDIC037_CP1_CS_AS 

Jednakże można zajrzeć do różnych rodzajów sortowania, aby upewnić się, że robi to, co chcesz po drugiej stronie planszy.

AKTUALIZACJA: Wspomniałeś o SQLite, jednak testowałem to na MSSQL. Nie jestem pewien, czy ta lista jest dostępna w SQLite, ale poniższe komentarze mogą zawierać przydatne informacje.

+1

OP faktycznie wspomniał o SQLite, ale może to zadziałać - nie wiem, czy istnieje istniejąca sekwencja porównywania w SQLite, która mogłaby załatwić sprawę - może trzeba ją utworzyć. –

+0

jak @DavidFaber zwrócił uwagę, rzeczywistą platformą docelową jest SQLite. Znalazłem http://sqlite.org/datatype3.html Ale nie mogę naprawdę zrozumieć, czy to rozwiązanie jest wykonalne w SQLite. – Nic

+0

Zaktualizowałem moją odpowiedź, dzięki –