如何在SQL特定列中按字母数字值排序

时间:2019-04-08 18:39:14

标签: sql sql-server sql-order-by

create table Employee(id int, Registration_no varchar(50),Name varchar(50))

insert into @Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into @Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into @Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into @Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into @Employee values(5,'DLW/TTC/19/8','RITESH')
insert into @Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into @Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into @Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into @Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into @Employee values(10,'DLW/TTC/19/10','ROSHNI')

select * from Employee

你好,我有上面的表格。 尝试订购此表的列时实际上遇到了问题(Registration_no) 因此,请帮助我根据其(Registration_no)列对其进行订购

其他列的排列方式无关紧要。我只希望我的Registration_no列按这样的特定顺序排列

Registration_no
DLW/TTC/19/1
DLW/TTC/19/2
DLW/TTC/19/3
DLW/TTC/19/4
DLW/TTC/19/5
DLW/TTC/19/6
DLW/TTC/19/7
DLW/TTC/19/8
DLW/TTC/19/9
DLW/TTC/19/10

7 个答案:

答案 0 :(得分:1)

这将按/字符串中最后一个Registration_No右边的数字排序。我只在结果集中包含SortColumn,以便您可以看到这些值。您可以从查询中忽略它。

SELECT 
  e.*,
  CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER) AS SortColumn
FROM @Employee AS e
ORDER BY
  CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER)

结果:

+----+-----------------+---------+------------+
| id | Registration_no |  Name   | SortColumn |
+----+-----------------+---------+------------+
|  3 | DLW/TTC/19/1    | RUPAK   |          1 |
|  2 | DLW/TTC/19/2    | RAJEEV  |          2 |
|  1 | DLW/TTC/19/3    | RAMESH  |          3 |
|  4 | DLW/TTC/19/4    | RAMLAAL |          4 |
|  9 | DLW/TTC/19/5    | SHRISTI |          5 |
|  6 | DLW/TTC/19/6    | HRITIK  |          6 |
|  8 | DLW/TTC/19/7    | RUPALI  |          7 |
|  5 | DLW/TTC/19/8    | RITESH  |          8 |
|  7 | DLW/TTC/19/9    | ROSHAN  |          9 |
| 10 | DLW/TTC/19/10   | ROSHNI  |         10 |
+----+-----------------+---------+------------+

SortColumn首先运行字符串REVERSE,然后使用CHARINDEX从最后一次出现/的字符串的末尾开始查找位置,然后取原始列右侧的数字-1(-1排除/本身)。

答案 1 :(得分:0)

如果Registration_no末尾的模式始终像B*/X,那么:

/XX

请参见demo

答案 2 :(得分:0)

当您尝试通过Registration_no进行排序时,您会注意到的第一件事是,由于varchar类型的列的字符串内容的性质,将按字母顺序对其进行排序。因此,正确的方法是将reg no的最后两个部分转换为数字,并在order by子句中使用它们。 (在这种情况下,由于倒数第二个总是19,因此我们只能使用最后一个部分)

进行一些搜索,我发现此函数“ Parsename”在复制方案中很有用,因为它会将SQL对象模式名称拆分为各个组成部分,因此我们可以在这里使用它(只要reg不包括任何部分)不超过4个部分(“ SQL对象的最大部分”)

因此,在这种情况下,它在SQL Server(T-SQL)中将起作用:

SELECT * 
FROM Employee 
order by cast(Parsename(replace(Registration_no,'/','.'),1) as int)

More info here

谢谢

答案 3 :(得分:0)

您可以将reverse函数与charindex函数一起使用

SELECT e.*, cast( reverse(substring(reverse(Registration_no),1,
             charindex('/',reverse(Registration_no),1) -1 ) ) as int ) as nr
  FROM employee e
 ORDER BY nr;

Demo

主要原理是提取段并将其转换为字符串值尾部的数字值,例如整数。如果使用substring函数来使字符串反向读取,则从使用reverse函数开始到此提取操作要容易得多。在这种情况下,我们需要通过贡献charindex函数来确定第一个定界符(/)的位置。所有这些功能自2008年版本开始就存在。

答案 4 :(得分:0)

尽管我不喜欢数字的提取方式,但这是可以做到的

select cast(substring(registration_no, charindex('/', registration_no, len(registration_no) -3) + 1, 3) as int), 
    * from Employee 
    order by 1

假设您要出于显示目的订购它,我建议您使用正则表达式在前端对其进行订购。

答案 5 :(得分:0)

如何?

select *
from Employee
order  by LEFT(Registration_no,PATINDEX('%[0-9]%',Registration_no)-1)-- alpha sort
, CONVERT(INT,REPLACE(SUBSTRING(Registration_no,PATINDEX('%[0-9]%',Registration_no),PATINDEX('%[0-9]%',Registration_no)),'/', '')) -- number sort

答案 6 :(得分:-1)

尝试此查询。

create table #Employee(id int, Registration_no varchar(50),Name varchar(50))

insert into #Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into #Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into #Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into #Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into #Employee values(5,'DLW/TTC/19/8','RITESH')
insert into #Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into #Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into #Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into #Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into #Employee values(10,'DLW/TTC/19/10','ROSHNI')


select * from #Employee
order by Registration_no
id          Registration_no                                    Name
----------- -------------------------------------------------- --------------------------------------------------
3           DLW/TTC/19/1                                       RUPAK
10          DLW/TTC/19/10                                      ROSHNI
2           DLW/TTC/19/2                                       RAJEEV
1           DLW/TTC/19/3                                       RAMESH
4           DLW/TTC/19/4                                       RAMLAAL
9           DLW/TTC/19/5                                       SHRISTI
6           DLW/TTC/19/6                                       HRITIK
8           DLW/TTC/19/7                                       RUPALI
5           DLW/TTC/19/8                                       RITESH
7           DLW/TTC/19/9                                       ROSHAN