我想对文本列进行排序,其中数字组件应按数字排序。排序结果应如下所示:
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
以下规则适用:
chrx
被视为chr22
chry
被视为chr23
chrmt
被视为chr24
chr6_ux9
是一个特殊情况,应该在chr6
我尝试了不同的方法,但无法找到完美的解决方案。如果有人有想法,请帮助我。
答案 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
类型没有留下任何空间在6
和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_ux9
在此方案中自动chr6
之后。
答案 1 :(得分:1)
不是一个完美的数据模型,所以说...你应该通过使用适当的规范化模型来解决这个问题,但你也可以使用array datatype。可以对数组进行排序,索引等。