Как отсортировать varchar в SQL?

#sql #ms-access #sql-order-by

#sql #ms-access #sql-порядок по

Вопрос:

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

Одобрено, пункт 2, …, Пункт 10, Пункт 11, …, Пункт 21

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

Комментарии:

1. Это потому, что вы выполняете лексикографическую сортировку . То, что вы ищете, — это комбинированная лексикографическая и числовая сортировка. Вероятно, вам придется обрабатывать это вручную.

2. Вы все еще можете отсортировать его в предложении WHERE, но вам нужно разделить текстовый столбец на текст число, где вы дополняете число пробелами или нулями. Но вам нужно разработать схему разделения его таким образом, чтобы он обрабатывал значения, которые не соответствуют шаблону «<текст><число>».

3. Самым простым способом, если вы в состоянии изменить данные, было бы добавить начальный 0 к однозначным значениям, т.е. «Точка 2» станет «Точкой 02». Очевидно, что это может стать неуправляемым, если у вас много записей, хотя необходимость менять «Точку 2» на «Точку 0002», чтобы она появилась раньше «Точки 1000», может оказаться нежелательной.

4. У меня нет доступа к изменению данных, но ваша точка зрения верна. Спасибо!!!

5. @csl : как вы предлагаете использовать предложение WHERE для выполнения сортировки ay?

Ответ №1:

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

например,

 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.

Комментарии:

1. Чтобы заставить это работать в Access, вам нужно Order By left(foo,InStr(foo," ")), clng(right(foo, len(foo) - instr(foo," "))) и, конечно же, выбрать from что-нибудь! 😉

2. @ CREsults: Спасибо. Он показывает несоответствие типов данных мне, когда я пытаюсь упорядочить по предложению «clng(right(Session, len(Session) — instr(Session,’ ‘)))»

3. @Conrad Frix — нет, но это лучше справилось бы с ситуацией «Точки 11 A».

4. ORDER BY 2, 3 на мой взгляд, выглядит намного приятнее.

5. Значение Val («11 A») дает 11. CLng («11 A») выдает ошибку несоответствия типов.

Ответ №2:

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

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

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

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

Тогда легко делать такие вещи, как

 SELECT IIF(IsApproved, "Approved", "Point " amp; [Point]) as output
FROM 
    table
WHERE
    IsApproved = true or Point < 10
ORDER BY
  IsApproved,
  Point
  

Ответ №3:

Не уверен насчет access, но если есть функция replace, то вы могли бы сделать что-то вроде этого (например, в sql server):

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

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

Комментарии:

1. Диалект Access SQL не включает replace -но Access позволяет вам включать (некоторые) функции VBA в ваши инструкции SQL (включая VBA Replace ).

Ответ №4:

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

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

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

Ответ №5:

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

 SELECT * From MyTable
Order By Int(Replace(MyColumn,'Point',''))