【问题标题】:SQL Server - Sorting column based on string and numberSQL Server - 根据字符串和数字对列进行排序
【发布时间】:2019-03-14 07:28:58
【问题描述】:

我有一个表,其中有一列包含字符串和数字的组合,如下所示。我需要按降序或升序对名称列进行排序,但问题是当我使用 ORDER BY 时,它没有按预期排序

我的查询如下图所示

SELECT * FROM test ORDER BY `name` ASC

我的预期结果如图所示

employee1
employee2
employee3
employee6
employee6
employee10
employee11
employee12
employee17
employee82
employee100
employee111
employee129
employee299

谁能帮我解决这个问题

【问题讨论】:

  • 整个结果集中的字母部分或文本是固定的,还是employee1 在一行,manager3 在另一行?如果是后者,你想如何排序呢?仅基于数字?基于数字然后文本?基于文本而不是数字?另外,数字总是在最后还是可以是1employeeemployee3

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


【解决方案1】:

您可以通过仅从字段中提取数字部分来尝试以下操作

SELECT * FROM test 
ORDER BY cast(replace(`name`,'employee','') as int) ASC

【讨论】:

  • 感谢您的回复...看起来不错...但问题是没有受赠者确切的字符串是什么。仅举个例子,我使用了 employee
【解决方案2】:

请尝试以下代码:

-- ASSUMES NUMBERS ARE IN THE LAST CHARACTER
-- WONT WORK IF NUMBER IS THERE IN THE MIDDLE

DROP TABLE IF EXISTS #data

select 
 Name        = REPLACE(name,' ','') 
,NameWithNum = REPLACE(name,' ','') + cast(object_id as varchar(100))
INTO #data
from sys.tables

SELECT 
 NameWithNum
,NameRemovedNumbers= SUBSTRING(NameWithNum, PATINDEX('%[0-9]%', NameWithNum), LEN(NameWithNum))
from #data
ORDER BY Name,SUBSTRING(NameWithNum, PATINDEX('%[0-9]%', NameWithNum), LEN(NameWithNum))

【讨论】:

  • 如果字符串中包含特殊字符会怎样
  • 让我们说employee2-555
【解决方案3】:

由于数字总是在最后,你可以这样做

WITH CTE AS
(
SELECT 'employee1' Name
union all select 'employee2'
union all select 'employee3'
union all select 'employee6'
union all select 'employee6'
union all select 'employee10'
union all select 'employee11'
union all select 'employee12'
union all select 'employee17'
union all select 'employee82'
union all select 'employee100'
union all select 'employee111'
union all select 'employee129'
union all select 'employee299'
)
SELECT Name
FROM CTE
ORDER BY CAST(SUBSTRING(Name, PATINDEX('%[^a-z, '' '']%', Name), LEN(Name)) AS INT)
--OR PATINDEX('%[0-9]%', Name)

或者

WITH CTE AS
(
SELECT 'The First Employee 1' Name
union all select 'The Second One 2'
union all select 'Employee Number 4'
union all select 'Employee Number 3'
)
SELECT Name
FROM CTE
ORDER BY CAST(SUBSTRING(Name, PATINDEX('%[0-9]%', Name), LEN(Name)) AS INT)

这是一个 Live Demo,您可以在其中更改字符串并查看结果。

最后,我要指出真正的问题,只有一列且没有 PK 的表

【讨论】:

  • 让我们说 employee2-555
【解决方案4】:

名称的“基础”部分是相同的。因此,您可以按长度排序,然后按名称排序:

SELECT t.*
FROM test t
ORDER BY LEN(name), name;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多