SQL Server中子编号内的查询顺序

时间:2019-02-25 20:09:52

标签: sql sql-server

通常选择这样时,我有一列数据类型为varchar

column
------
1
2
3
4Answer
4
5
1_1Answer
1_2Answer
2Answer
6
7
8
10Answer
9
10

我希望像这样按编号和子编号对结果进行排序

column
-----
1
1_1Answer
1_2Answer
2
2Answer
3
4
4Answer
5
6
7
8
9
10
10Answer

我有很多这样的数据,子编号中有20多个

5 个答案:

答案 0 :(得分:2)

这称为“自然排序”,大多数数据库默认情况下不支持此功能。

就我而言,我在postgres中编写了存储过程以解决此问题。我不知道您的数据库软件是哪个。 google'natsort'

更新:进入PC。这是我在postgres中使用的东西(部分在此处,在stackowerflow上找到):

      /* Split the input text into contiguous chunks where no numbers appear,
      and contiguous chunks of only numbers. For the numbers, add leading
      zeros to 20 digits, so we can use one text array, but sort the   
      numbers as if they were big integers.                               

        For example, human_sort('Run 12 Miles') gives                     
             ['Run ', '00000000000000000012', ' Miles']
   */                                                                     
   select array_agg(                                                     
     case                                                                 
       when a.match_array[1]::text is not null                            
         then a.match_array[1]::text                                      
       else lpad(a.match_array[2]::text, 20::int, '0'::text)::text        
     end::text)                                                           
     from (                                                               
       select regexp_matches(                                             
         case when $1 = '' then null else $1 end, E'(\\D+)|(\\d+)', 'g'   
       ) AS match_array                                                   
     ) AS a                                                               

用法:`选择.....按natsort(field)排序

答案 1 :(得分:2)

对于列出的示例数据,您可以使用查询

--Create example table to use
CREATE TABLE #Test ([Column] VarChar(50))

--Add example data to the example table
INSERT INTO #Test([Column]) VALUES
('1'),
('2'),
('3'),
('4Answer'),
('4'),
('5'),
('1_1Answer'),
('1_2Answer'),
('2Answer'),
('6'),
('7'),
('8'),
('10Answer'),
('9'),
('10')

--Select data from the table, ordering by the number part at the beginning of the column, and then by the whole column
SELECT [Column]
  FROM #Test
  ORDER BY
    CASE 
    WHEN PATINDEX('%[_a-z]%', [Column]) = 0 THEN TRY_CONVERT(INT, [Column]) 
    ELSE TRY_CONVERT(INT, LEFT([Column], PATINDEX('%[_a-z]%', [Column]) -1))
  END,
  [Column]

答案 2 :(得分:2)

假设您只有一个子编号,则可以将前导数字加下划线转换为十进制值,然后在order by中使用该数字:

order by convert(decimal(10, 4),
                 replace(left(column,
                              patindex('%[^0-9_]%', column + 'x') - 1
                             ), '_', '.'
                        )
                )

答案 3 :(得分:1)

我不知道我是否将以下查询弄乱了,但尝试了一下。我在下面的查询中所表示的意思是单位/单词的所有列作为组,而其他列作为子组。

      Select column over
               (Partition by 
             column where column 
         like '%Answer%' ) from 
        table group by column  order by 
          column;

答案 4 :(得分:0)

如果您碰巧使用oracle,可以这样做:

order by substr(your_column, 1, 1) asc