【问题标题】:Issues with query order查询顺序问题
【发布时间】:2018-05-17 03:53:58
【问题描述】:
我必须像这样订购以下类别:
1
2
3
4
5
6A
6B
6C
6D
7A
7B
10
11
12
我将如何通过 SQL 查询完成此操作?
我试过了:
Select *
From table
Order By len(category_name), category_name
但他们是这样订购的:
1
2
3
4
5
10
11
12
6A
6B
6C
6D
7A
7B
任何帮助将不胜感激!
【问题讨论】:
标签:
sql-server
tsql
sql-order-by
sql-server-2014
【解决方案1】:
您可以使用 标量值函数(有关标量值函数的更多信息 here)从类别名称中删除字母(有关此特定函数的更多信息 here)和使用结果对您的数据进行排序:
--1. declare a new function that removes all letters from your category name
--1.1 if the function already exists delete it
if OBJECT_ID('fx_remove_letters') is not null
drop function fx_remove_letters
go
--1.2 create a function to remove all letters (CHAR(65) is letter A, char(90) is letter Z)
create function fx_remove_letters(@str NVARCHAR(max))
returns NVARCHAR(max)
as
begin
DECLARE @loop INT
SET @loop = 0
WHILE @loop < 26
BEGIN
SET @str = REPLACE(@str, CHAR(65 + @loop), '')
SET @loop = @loop + 1
END
return @str
end
go
--2. this table variable holds your categories in a random order
declare @tmp table (category_name nvarchar(10))
--3. populate the test table variable
insert into @tmp
values('6D'),('2'),('3'),('12'),('5'),('6C'),('6B'),
('1'),('7A'),('4'),('7B'),('10'),('11'),('6A')
--4. select your data ordering them with the function we defined at the beginning
select category_name
from @tmp
order by cast(dbo.fx_remove_letters(category_name) as int), category_name
这是订购前的表格:
现在order by之后的结果:
【解决方案2】:
这有用吗?
SELECT category_name
FROM #Table1
ORDER BY
CASE ISNUMERIC(category_name)
WHEN 1 THEN REPLICATE('0', 10 - LEN(category_name)) + category_name
ELSE REPLICATE('0', 10 - LEN(category_name)+1) + category_name
END
如果您的输入中有 '6AA'、'6AB'.. 等,您可以使用以下查询:
SELECT category_name
FROM #Table1
ORDER BY
CASE
WHEN ISNUMERIC(category_name) =1
THEN REPLICATE('0', 10 - LEN(category_name)) + category_name
ELSE
REPLICATE('0', 10 - LEN(category_name)+LEN(STUFF(category_name, PATINDEX('%[^a-zA-Z]%',category_name),1,''))) + category_name
END