-1

我想对文本列进行排序,其中数字组件应按数字排序。排序后的结果应如下所示:

chr1
chr1,chr1
chr1,chr2
chr1,chr10
chr2
chr2,chr1
chr2,chr2
chr2,chr10
chr6
chr6,chr1
chr6_ux9
chr6_ux9,chr1
chr7
chr10
chr10,chr1
chr10,chr2
chr10,chr10
chr21
chr21,chr1
chr21,chr2
chr21,chr10
chrx
chrx,chr1
chrx,chr2
chrx,chr10
chry
chry,chr1
chry,chr2
chry,chr10
chrmt
chrmt,chr1
chrmt,chr2
chrmt,chr10
chr25
chr25,chr1
chr25,chr2
chr25,chr10

以下规则适用:

  1. chrx被视为chr22
  2. chry被视为chr23
  3. chrmt被视为chr24
  4. chr6_ux9是一个应该出现的特殊情况chr6

我尝试了不同的方法,但无法找到完美的解决方案。如果有人有想法,请帮助我。

4

2 回答 2

2

我现在明白了,你在找什么。您希望数字组件按数字排序,而不是字符串。这应该适合你:

SELECT col1
FROM   tbl
ORDER  BY string_to_array(
             replace(replace(replace(replace(replace(replace(
                col1
              , 'chrx',     'chr22')
              , 'chry',     'chr23')
              , 'chrmt',    'chr24')
              , 'chr6_ux9', 'chr6.6')
              , ' chr',     'chr')
              , 'chr',      '')
           , ',')::real[];

按照问题中的描述对列进行排序。文本组件('chr')原来是多余的噪音。应用所有替换后,我去除噪音并转换为可在ORDER BY子句中使用的数字数组。

在执行列出的替换时,特殊情况 forchr6_ux9强制使用real[]to 而不是更简单和更快的int[],因为integer类型在6and之间没有空间7。您还有一列带有空格而不是逗号。我也添加了一个替代品。但这可能只是一个错字。删除不相关的字符串后chr,只剩下逗号分隔的数字,可以转换为real[].

顺便说一句,replace()速度非常快。replace()我有连续执行数十个操作的函数,它们仍然执行得很快。(regexp_replace()慢得多。)


对单个元素进行排序的替代答案

对于所有值作为字符串的排序输出:

SELECT regexp_split_to_table(replace(replace(replace(
          col1
        ,'chrx', 'chr22')
        ,'chry', 'chr23')
        ,'chrmt', 'chr24')
        , ',') AS col1
FROM   tbl
ORDER  BY 1

chr6_ux9chr6在这种情况下会自动出现。

于 2012-05-01T18:45:34.207 回答
1

可以说不是一个完美的数据模型......您应该通过使用适当的规范化模型来解决这个问题,但您也可以使用数组数据类型。可以对数组进行排序、索引等。

于 2012-05-01T18:40:24.147 回答