ORDER BY列包含文本和数字数据的混合

时间:2012-05-01 18:27:43

标签: sql arrays postgresql replace sql-order-by

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

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
  5. 之后

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

2 个答案:

答案 0 :(得分: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[];

按照questin中的描述对列进行排序。文本组件('chr')证明是冗余噪声。在应用所有替换之后,我将噪声去掉并转换为可以在ORDER BY子句中使用的数值数组。

在执行列出的替换时,chr6_ux9的特殊情况强制使用real[]而不是更简单,更快int[],因为integer类型没有留下任何空间在67之间。您还有一列空格而不是逗号。我也添加了替代品。但这可能只是一个错字。删除不相关的字符串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_ux9在此方案中自动chr6之后。

答案 1 :(得分:1)

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