简体   繁体   English

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

[英]How to ORDER BY Alphanumeric values in SQL specific columns

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

Hello I have the table given above. 您好,我有上面的表格。 Actually am facing problem while am trying to order this table's column (Registration_no) So kindly help me to ORDER it according to its (Registration_no) column 尝试订购此表的列(Registration_no)时实际上遇到问题,请帮助我根据其(Registration_no)列对其进行订购

Its not matter that how the other columns are arranged. 其他列的排列方式无关紧要。 I just want my Registration_no column to be arranged in the specific order like this 我只希望我的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

This will sort by the digits to the right of the last / in the Registration_No string. 这将按Registration_No字符串中最后一个/右边的数字排序。 I'm only including the SortColumn in the result set so you can see the values. 我只在结果集中包括SortColumn ,以便您可以看到这些值。 You can omit it from your query. 您可以从查询中忽略它。

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)

Results: 结果:

+----+-----------------+---------+------------+
| 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 |
+----+-----------------+---------+------------+

The SortColumn functions first REVERSE the string, then use CHARINDEX to find the position from the end of the string of the last occurrence of / , then take that number -1 from the right side of the original column (-1 to exclude the / itself). SortColumn函数首先REVERSE字符串,然后使用CHARINDEX从最后一次出现的/的字符串末尾查找位置,然后从原始列的右侧获取数字-1(-1排除/本身)。

If the pattern at the end of Registration_no is always like /X or /XX then: 如果Registration_no末尾的模式始终像/X/XX则:

select * from Employee
order by 
  case left(right(Registration_no, 2), 1) 
    when '/' then 
      left(Registration_no, len(Registration_no) - 1) + '0' + right(Registration_no, 1)
    else Registration_no
  end

See the demo . 参见演示

The first thing you'll notice as you try to order by the Registration_no is that it will be ordered alphabetically due to the nature of the string contents of the column of type varchar. 尝试通过Registration_no进行排序时,您会注意到的第一件事是,由于varchar类型的列的字符串内容的性质,将按字母顺序对其进行排序。 So the correct way to do it is to convert the last two parts of the reg no into numbers and use them in an order by clause. 因此,正确的方法是将reg no的最后两个部分转换为数字,并在order by子句中使用它们。 (in this case we can use only the last part since the 2nd last is always 19) (在这种情况下,我们只能使用最后一部分,因为倒数第二个总是19)

Doing a bit of search I found this function 'Parsename' which has a usage in replication scenarios as it splits the SQL object schema name into its forming parts, so we can use it here (as long as the reg no parts doesn't exceed 4 parts "the SQL objects maximum parts") 经过一些搜索,我发现此函数“ Parsename”在复制场景中很有用,因为它会将SQL对象模式名称拆分为多个组成部分,因此我们可以在此处使用它(只要reg中的任何部分都没有超过4部分“ SQL对象最大部分”)

So this will work in that case in SQL Server (T-SQL): 因此,这将在这种情况下在SQL Server(T-SQL)中起作用:

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

More info here 更多信息在这里

Thanks 谢谢

You can use reverse function together with charindex function 您可以将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 演示版

The main principle is extracting the pieces and converting them to a numerical value, such as integer, in the tail part of the string values. 主要原理是提取片段并将其转换为字符串值尾部的数字值,例如整数。 It's easier to operate from the beginning with substring function to this extraction provided reverse function is used to make read the string reversely. 如果使用reverse功能来反向读取字符串,则从substring功能开始到提取操作都比较容易。 And in this case we need to determine the position of the first delimiter( / ) by contribution of charindex function. 在这种情况下,我们需要通过charindex函数的贡献来确定第一个定界符( / )的位置。 All those functions exist since the version 2008. 自2008版以来,所有这些功能都存在。

Although I dont like the way the number is extracted, this is how it can be done 尽管我不喜欢提取数字的方式,但这是可以完成的方式

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

I would suggest you order it on the frontend using regex assuming that you are wanting to order it for display purpose. 我建议您使用正则表达式在前端订购它,假设您要订购用于显示目的。

How about this. 这个怎么样。

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

Try this query. 试试这个查询。

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM