SQL Alpha数字排序问题

时间:2017-08-23 17:27:43

标签: sql sql-server sql-server-2008 natural-sort

我发现我们可以对表中的列进行排序,即使它是字母数字。

我唯一的问题是,如果列数据只是字符,则会抛出错误。

BEGIN TRAN

USE SomeDatabase
CREATE TABLE dbo.Section
(
       Section varchar(50) NULL
)
INSERT INTO dbo.Section (Section.Section) VALUES ('BB')
INSERT INTO dbo.Section (Section.Section) VALUES ('1 ')
INSERT INTO dbo.Section (Section.Section) VALUES ('AB 1')
INSERT INTO dbo.Section (Section.Section) VALUES ('A21')
INSERT INTO dbo.Section (Section.Section) VALUES ('B2')
INSERT INTO dbo.Section (Section.Section) VALUES ('A11')
INSERT INTO dbo.Section (Section.Section) VALUES ('B20')
INSERT INTO dbo.Section (Section.Section) VALUES ('B21')
INSERT INTO dbo.Section (Section.Section) VALUES ('AB10')
INSERT INTO dbo.Section (Section.Section) VALUES ('A10')
SELECT Section
FROM dbo.Section

SELECT Section
FROM dbo.Section
ORDER BY LEFT(Section,PATINDEX('%[0-9]%',Section)-1), -- alphabetical sort
         CONVERT(INT,SUBSTRING(Section,PATINDEX('%[0-9]%',Section),LEN(Section))) -- numerical sort

DROP Table dbo.Section

ROLLBACK

因此,排序'BB'是个问题。如果你删除BB然后一切正常。

3 个答案:

答案 0 :(得分:1)

查看代码时遇到的明显问题是PATINDEX如果找不到任何内容,将返回0。因为您有0 - 1作为长度,LEFT函数将抛出错误。

请改为尝试:

...
ORDER BY LEFT(Section
             ,CASE WHEN PATINDEX('%[0-9]%',Section) >= 2
                   THEN PATINDEX('%[0-9]%',Section) - 1
                   ELSE LEN(Section)
                   END
             ), -- alphabetical sort
     CASE WHEN PATINDEX('%[0-9]%',Section) >= 1
          THEN CONVERT(INT,SUBSTRING(Section,PATINDEX('%[0-9]%',Section),LEN(Section) - PATINDEX('%[0-9]%',Section) - 1))
          END -- numerical sort
...

答案 1 :(得分:1)

问题是Patindex在两个ord​​er by子句中都返回0。我在下面纠正了它。

- a graph proto (graph.pbtxt)
- a checkpoint (model.ckpt.data-00000-of-00001, model.ckpt.index, model.ckpt.meta)
- a frozen graph proto with weights baked into the graph as constants (frozen_inference_graph.pb) 

答案 2 :(得分:1)

您可以使用stuff()代替substring(),如下所示:

select section
  , alpha = left(section,patindex('%[0-9]%',section+'0')-1)
  , num   = stuff(section,1,patindex('%[0-9]%',section)-1,'')
from section
order by 
    left(section,patindex('%[0-9]%',section+'0')-1)
  , convert(int,stuff(section,1,patindex('%[0-9]%',section)-1,''))

rextester演示:http://rextester.com/JOXUEE9700

输出:

+---------+-------+------+
| section | alpha | num  |
+---------+-------+------+
| 1       |       | 1    |
| A10     | A     | 10   |
| A11     | A     | 11   |
| A21     | A     | 21   |
| AB 1    | AB    | 1    |
| AB10    | AB    | 10   |
| B2      | B     | 2    |
| B20     | B     | 20   |
| B21     | B     | 21   |
| BB      | BB    | NULL |
+---------+-------+------+