I have a query like this:
SELECT [Drug_id]
FROM tbl_Receiving
ORDER BY CAST(SUBSTRING([Drug_id], 3, LEN([Drug_ID])) as int)
but result is getting
A-1
A-10A
A-11
A-2
A-20A
A-21
A-22
A-3
A-30
A-31
But I need to get in all proper ascending order.
A-1
A-2
A-3
A-10
A-11
My [Drug_id] column is nvarchar(50)
If the string formatting is defined as you shown in your sample data, You can use SUBSTRING and CHARINDEX to split the string before (-) and the INT value after (-). Then you can apply Ordering on them to get your desired data.
Note: Ofcourse there are performance issue with those String operations.
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)
Try this: Run this query
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)
I've basically copied this from this answer: https://stackoverflow.com/a/16667778/9101689
It uses patindex to identify the position of the numeric values and substrings out the actual value. We take that substring and the use the LEFT function to trim everything out to the right and cast that value as an int to order.
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)
The value t is added so the patindex '%[^0-9]%' will return a non zero value in the case there is no non numeric suffix on drug_id field.
Or less readable:
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)
This won't work properly if you have a value like "A2-10A" though (or anything with more than one numeric value).
If your values are always of the form:
<letter>-<number><optional letter>
Then, you can do:
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
This treats the drug_id
as a string, using the length to control the ordering of the numbers. It works when:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.