Регулярное выражение для SQL Query для определения порядка с использованием первого «целого» числового значения в строке - PullRequest
0 голосов
/ 29 апреля 2019

Я пытаюсь добавить в запрос порядок, отличающийся от поведения по умолчанию, и мне не удалось найти ничего, что соответствует моему случаю. Самым близким, что я мог найти, было регулярное выражение в SQL для обнаружения одной или нескольких цифр

Корпус:

Заказать столбец по значениям: 1,4,2,20,10,1M, 1A, 11,10M, A, G, Z

Ожидаемый выход: 1, 1A, 1M, 2, 4, 10, 10M, 11, 20, A, G, Z

Текущий код C #, который я использую для достижения ожидаемого поведения:

query.OrderByDescending(x => x.CarClass.ClassCodeOrder).ThenByDescending(x => x.CarClass.ClassCode)

Где ClassCode:

[NotMapped]
public int ClassCodeOrder
{
   get {
      if (string.IsNullOrEmpty(ClassCode)) return 0;

      Regex re = new Regex(@"\d+");
      Match m = re.Match(ClassCode);
      if (m.Success)
      {
         return int.Parse(m.Value);
      }

      return 999;
  }
}

Вышеописанное работает нормально, однако теперь мне нужно упорядочить данные, возвращенные из хранимой процедуры, таким же образом.

Я пытался использовать:

CREATE FUNCTION dbo.udf_GetNumeric
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
GO

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

Тип решения, который я имел в виду, выглядит примерно так:

SELECT CASE WHEN ISNUMERIC(SUBSTRING(LTRIM(Description), 1, 1)) = 1 
         THEN 'yes' 
         ELSE 'no' 
       END AS StartsWithNumber
FROM Questions 

Без ограничения проверки только первого значения.

Есть ли какой-нибудь простой код SQL, который я мог бы использовать для достижения этой цели?

Самое близкое, что я смог прийти:

SELECT * 
FROM  CarClass 
WHERE  1 = 1
ORDER BY ClassCode, CONVERT(INT, SUBSTRING(ClassCode, PATINDEX('_[0-9]_', ClassCode), 1))
,LEFT(ClassCode, PATINDEX('%[0-9]%', ClassCode))

Но это возвращает: 1 10 11 12 123 13 14 15 16 1M 2 2M 3 4 4H 5 6 7 8 9 AM В BM С D Е F г M S T X

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...