Как отсортировать varchar в SQL? - PullRequest
3 голосов
/ 25 мая 2011

В SQL (с использованием Access) у меня есть следующие значения в столбце:

Утверждено, точка 2, ..., точка 10, точка 11, ..., точка 21

Теперь, если бы я использовал порядок по column asc, точка 11 предшествует точке 2. Я хочу, чтобы точка 2, точка 3 предшествовали точке 11. Как это сделать?

Ответы [ 5 ]

3 голосов
/ 25 мая 2011

Если вы знаете , что они всегда будут в форме «имя-номер», вы можете добавить два столбца, разделенных на этот исходный столбец, и вместо этого отсортировать ихоригинала

например,

SELECT foo2.foo, 
    Left(foo,InStr(foo," ")) AS foo_name, 
    CLng(IIf(InStr(foo," ")>0, Right(nz(foo,0),
            Len(nz(foo,0))-InStr(nz(foo,0)," ")),"0")) AS foo_number
FROM foo2
ORDER BY Left(foo,InStr(foo," ")), 
    CLng(IIf(InStr(foo," ")>0, Right(nz(foo,0),
            Len(nz(foo,0))-InStr(nz(foo,0)," ")),"0"));

(закодировано И проверено)

Это должно дать вам такие результаты, как:

foo       foo_name  foo_number
---       --------  ----------
Approved  Approved  
Point 2   Point     2
Point 10  Point     10
Point 11  Point     11
Point 21  Point     21

и сортировкабудет работать с частью foo_number.

2 голосов
/ 25 мая 2011

Я проверил это, и кажется, что Access "достаточно умен", чтобы знать, что вы хотите.Это минимум, который вам нужно сделать.

SELECT YourFields
FROM YourTable
ORDER BY 
   PointColumn,
   Mid([PointColumn],6)

Этот подход и другие подобные ему не SARGable , поэтому, если вы хотите фильтровать записи < Point 10, это будет медленным.

Так что вместо этого я рекомендую вам нормализовать ваши данные.Добавьте поле с именем IsApproved (логическое значение) и добавьте еще одно поле с именем point, которое отслеживает точки

Тогда можно легко сделать такие вещи, как

SELECT IIF(IsApproved, "Approved", "Point " & [Point]) as output
FROM 
    table
WHERE
    IsApproved = true or Point < 10
ORDER BY
  IsApproved,
  Point
0 голосов
/ 25 мая 2011

Для краткости ..

SELECT * From MyTable
Order By Int(Replace(MyColumn,'Point',''))
0 голосов
/ 25 мая 2011

Что касается производительности, обычных уловок два:

  1. Сортировка с использованием varcharcol, intcol (varcharcol, содержащий "Point" и intcol, содержащий число)

  2. Добавьте дополнительный индексированный столбец, который содержит «Точку 000001», «Точку 000010», «Точку 000020» и т. Д. С достаточным количеством нулей для размещения того, что вам нужно.

0 голосов
/ 25 мая 2011

Не уверен насчет доступа, но если есть функция замены, вы можете сделать что-то вроде этого (например, в SQL Server):

select      *, cast ( replace( replace( pointColumnName, 'Point', ''), 'Approved', 1000) as int )  as points
from        tblName
order       by points

где tblName - таблица, а pointColumnName - столбец с вашими данными.

...