如何对var length ids(复合字符串+数字)进行排序?

时间:2011-06-01 15:17:58

标签: mysql sorting primary-key

我有一个MySQL数据库,其密钥属于这种类型:

A_10
A_10A
A_10B
A_101
QAb801
QAc5
QAc25
QAd2993

我希望他们首先按照alpha部分排序,然后按数字部分排序,就像上面一样。我希望这是此列的默认排序。

1)我如何按上述指定排序,即写一个MySQL函数?
2)如何将此列设置为默认使用排序例程?

一些可能有用的约束:我的ID的数字部分永远不会超过100,000。我在一些javascript代码中使用这个事实将我的ID转换为将非数字部分与(数字+ 1,000,000)连接起来的字符串。 (当时我没有注意到上面的变体/子部分,例如A_10A,A_10B,所以我不得不重新修改我的代码部分。)

2 个答案:

答案 0 :(得分:2)

实现所需内容的最佳方法是将每个部分存储在自己的列中,我强烈建议更改表结构。如果不可能,您可以尝试以下方法:

创建3个UDF,它返回字符串的前缀,数字部分和后缀。为了获得更好的性能,它们应该是原生的(Mysql,与任何其他RDMS一样,在复杂的字符串解析中并不是很好)。然后,您可以在ORDER BY子句或触发器体中调用这些函数来验证您的列。在任何情况下,它都会比创建3列时慢。

答案 1 :(得分:0)

我所知道的答案并不简单。我曾经有类似的东西,但不得不使用jQuery对它进行排序。所以我所做的是首先将输出转换为javascript数组。然后,您可能希望在数字中插入零填充。使用正则表达式将Alpha与Nummerics分开,然后重新组合数组:

var zarr = new Array();

for(var i=0; i<val.length; i++){

    var chunk = val[i].match(/(\d+|[^\d]+)/g).join(',');
    var chunks = chunk.split(",");

    for(var s=0; s<chunks.length; s++){

        if(isNaN(chunks[s]) == true)
            zarr.push(chunks[s]);
        else
            zarr.push(zeroPad(chunks[s], 5));

    }
}

function zeroPad(num,count){ 
var numZeropad = num + '';
while(numZeropad.length < count) {

numZeropad = "0" + numZeropad; 
}
return numZeropad;
}

你最终会得到一个像这样的数组:

A_00100
QAb00801
QAc00005
QAc00025
QAd02993

然后你可以做一个自然的排序。我知道你可能想通过直接的MySQL来做,但我不确定它是否进行自然排序。

祝你好运!