Как я могу принять порядок при использовании столбца nvarchar в SQL - PullRequest
0 голосов
/ 20 июня 2019

У меня есть такой запрос:

SELECT [Drug_id]
FROM tbl_Receiving
ORDER BY CAST(SUBSTRING([Drug_id], 3, LEN([Drug_ID])) as int)

, но результат получается

A-1
A-10A
A-11
A-2
A-20A
A-21
A-22
A-3
A-30
A-31

Но мне нужно получить все в порядке возрастания.

   A-1
   A-2
   A-3
   A-10
   A-11

Мой столбец [Drug_id] - nvarchar (50)

Ответы [ 5 ]

0 голосов
/ 20 июня 2019

Если ваши значения всегда имеют форму:

<letter>-<number><optional letter>

Затем вы можете сделать:

order by (case when drug_id like '%[A-Z]'
               then len(drug_id) - 1  -- ignore the last character
               else len(drug_id)
          end)
         drug_id

Это обрабатывает drug_id как строку, используя длину дляконтролировать порядок номеров.Он работает, когда:

  • числа являются целыми числами
  • числа не дополняются нулями
  • префикс имеет фиксированную длину
0 голосов
/ 20 июня 2019

Я в основном скопировал это из этого ответа: https://stackoverflow.com/a/16667778/9101689

Он использует patindex для определения позиции числовых значений и подстрок из фактического значения. Мы берем эту подстроку и используем функцию ВЛЕВО, чтобы обрезать все вправо и приводить это значение как int к порядку.

declare @d table (drug_id nvarchar(max))
insert into @d values ('A-1'),('A-10A'),('A-11'),('A-2'),('A-20A'),('A-21'),('A-22'),('A-3'),('A-30'),('A-31')
SELECT *
FROM (
    SELECT ORD_subsrt = SUBSTRING(drug_id, ORD_pos, LEN(drug_id)), *
    FROM (
        SELECT ORD_pos = PATINDEX('%[0-9]%', drug_id), *
        FROM @d
    ) d
) t
Order by cast(LEFT(ORD_subsrt, PATINDEX('%[^0-9]%', ORD_subsrt + 't') - 1) as int)

Значение t добавляется, так что patindex "% [^ 0-9]%" вернет ненулевое значение в случае, если в поле drug_id нет нечислового суффикса.

или менее читаемый:

SELECT *
From @d
Order by cast(LEFT(SUBSTRING(drug_id, PATINDEX('%[0-9]%', drug_id), LEN(drug_id)), PATINDEX('%[^0-9]%', SUBSTRING(drug_id, PATINDEX('%[0-9]%', drug_id), LEN(drug_id)) + 't') - 1) as int)

Это не будет работать должным образом, если у вас есть значение типа «A2-10A» (или что-либо с более чем одним числовым значением).

0 голосов
/ 20 июня 2019

Если форматирование строки определено так, как показано в ваших данных примера, вы можете использовать SUBSTRING и CHARINDEX, чтобы разделить строку до (-) и значение INT после (-). Затем вы можете подать заявку на них, чтобы получить нужные данные.

Примечание. Конечно, с этими операциями String возникают проблемы с производительностью.

SELECT *
FROM your_tabele
ORDER BY SUBSTRING(val,1,CHARINDEX('-',Val,1)-1),
CAST(SUBSTRING(val,CHARINDEX('-',Val,1)+1,LEN(val)-CHARINDEX('-',Val,1)) AS INT)
0 голосов
/ 20 июня 2019

Попробуйте это: Запустите этот запрос

    select substring(drug_id,1,CHARINDEX('-',drug_id)) + convert(varchar,cast(substring(drug_id,CHARINDEX('-',drug_id)+1,len(drug_id)) as int)) id from tbl_Receiving
order by  cast(substring(drug_id,CHARINDEX('-',drug_id)+1,len(drug_id)) as int)
0 голосов
/ 20 июня 2019

Предполагая, что ваш формат всегда A-<NUMBER>, вы всегда можете сделать следующее:

SELECT 
    [Drug_id]
FROM 
    tbl_Receiving
ORDER BY 
    CAST(SUBSTRING([Drug_id], 3, LEN([Drug_ID])) as int)

В этом случае вы будете пытаться использовать только число с номерами int

.

Вывод будет следующим:

enter image description here

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