确定ORDER BY语句中的顺序

时间:2012-04-12 11:28:14

标签: php mysql

我有一个选择声明:

$search = "SELECT Scene, Divinite, Attestation
    FROM SceneDivList
    WHERE BINARY Divinite = '$target'
    ORDER BY FIELD( Scene);
$result = mysql_query($search, $con);

在这种情况下,结果将根据字段“场景”按字母顺序排列。

是否可以按字母顺序排序结果,但基于以下“字母”:

$alphabet = array( 1 => '-' , 2 => ',' , 3 => '.' , 4 => "A",
                   5 => "j", 6 => "a", 7 => "w", 8 => "b", 
                   9 => "p", 10 => "f", 11 => "m", 12 => "n", 
                   13 => "r", 14 => "h", 15 => "H", 16 => "x", 
                   17 => "X", 18 => "s", 19 => "S", 20 => "q", 
                   21 => "k", 22 => "g", 23 => "t", 24 => "T", 
                   25 => "d", 26 => "D");

结果应该是:

SCENE            ATTESTATION
jnD-Hr-m-nms,t  DI.80,11
jrp             DI.26,12
jrT,t           DI.116,17
aAb,t           DI.138,8
anx             DI.12,5
antjw           DI.148,10
wADw-msdm,t     DI.144,11
bHsw            DI.115,9
pr-n-nb=f           DI.17,7

5 个答案:

答案 0 :(得分:2)

最干净的解决方案是define your own custom collation并指定Scene列应该使用它。如果你这样做,查询将只是阅读ORDER BY Scene,那就是它(顺便说一下,ORDER BY FIELD(Scene)没有意义 - 你看看FIELD做了什么吗?)。

除此之外,您可以根据STR_REPLACE将噩梦混为一谈,以使数据适应整理而不是相反,但我不会去那里。

当然,您可以回避所有这些并在PHP中进行排序,这将更方便,但这种方法不适用于加入必须自行排序的子查询的查询。

答案 1 :(得分:1)

Jon的回答是最好的解决方案。但是这里有一个残酷的php解决方案

$alphabet = array( 1 => '-' , 2 => ',' , 3 => '.' , 4 => "A",
               5 => "j", 6 => "a", 7 => "w", 8 => "b", 
               9 => "p", 10 => "f", 11 => "m", 12 => "n", 
               13 => "r", 14 => "h", 15 => "H", 16 => "x", 
               17 => "X", 18 => "s", 19 => "S", 20 => "q", 
               21 => "k", 22 => "g", 23 => "t", 24 => "T", 
               25 => "d", 26 => "D");

$replace_engine = 'Scene';                   
foreach($alphabet as $k=>$char) {
    $charint = sprintf("%03s",   $k);
    $replace_engine = "REPLACE(".$replace_engine.",'$char','$charint')";
}


$query = "SELECT $replace_engine as myalphabet, Scene FROM SceneDivList ORDER BY myalphabet"; 

答案 2 :(得分:0)

有两种解决方案: 1)直接在代码中查询后的订单。缺点是您总是需要收集所有结果,以免出现性能问题。 2)使用基于数组索引的排序值向表中添加一列。

也许你可以创建一个mysql函数来订购...但我不知道足够的自定义mysql函数

...... Jon在我提前2分钟提出的解决方案:D

答案 3 :(得分:0)

虽然Jon的答案是正确的方法,但您可能希望通过设置一个表(ID,C)来尝试快速和脏的版本,其中ID是(自动增量)整数,C是VARCHAR(1)。

通过连接,可以达到所需的任何级别。

$search = "SELECT s.Scene, s.Divinite, s.Attestation
FROM SceneDivList s
INNER JOIN CustomOrder o1 ON o1.C = SUBSTRING(s.Scene,0,1)
INNER JOIN CustomOrder o2 ON o2.C = SUBSTRING(s.Scene,1,1)
INNER JOIN CustomOrder o3 ON o3.C = SUBSTRING(s.Scene,2,1)
WHERE BINARY s.Divinite = '$target'
ORDER BY o1.ID, o2.ID, o3.ID, SUBSTRING(s.Scene,4);
$result = mysql_query($search, $con);

注意:虽然这可以快速完成脏查询本身会比以前慢。

答案 4 :(得分:0)

如果你想用字符串替换字段并按它排序,你需要PHP中的递归函数来生成字符串:

function replace( $fields ) {
    if( empty( $fields ) ) return( "`Scene`" );

    $t = each( $fields );
    $pop = array_shift( $fields );

    return( sprintf(
        "replace(%s, '%s', '%s')",
        replace($fields),
        $t['key'],
        str_pad($t['value'], 3, '0', STR_PAD_LEFT )
    ));
}

$alphabet  = array( 1 => '-' , 2 => ',' , 3 => '.' , 4 => "A",
                   5 => "j", 6 => "a", 7 => "w", 8 => "b", 
                   9 => "p", 10 => "f", 11 => "m", 12 => "n", 
                   13 => "r", 14 => "h", 15 => "H", 16 => "x", 
                   17 => "X", 18 => "s", 19 => "S", 20 => "q", 
                   21 => "k", 22 => "g", 23 => "t", 24 => "T", 
                   25 => "d", 26 => "D");



$sql = sprintf(
"SELECT Scene, Divinite, Attestation, %s as `neworder`
FROM SceneDivList
WHERE BINARY Divinite = '%s'
ORDER BY `neworder`", 
    replace(array_flip( $alphabet  )),
    "target <- whatever that is"
);

echo $sql;

此时$ sql将包含以下查询:

SELECT Scene, Divinite, Attestation, 
replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(
`Scene`, 'D', '026'), 'd', '025'), 'T', '024'
), 't', '023'), 'g', '022'), 'k', '021'), 'q', '020'
), 'S', '019'), 's', '018'), 'X', '017'), 'x', '016'
), 'H', '015'), 'h', '014'), 'r', '013'), 'n', '012'
), 'm', '011'), 'f', '010'), 'p', '009'), 'b', '008'
), 'w', '007'), 'a', '006'), 'j', '005'), 'A', '004'
), '.', '003'), ',', '002'), '-', '001'
) as `neworder`
FROM SceneDivList
WHERE BINARY Divinite = 'target <- whatever that is'
ORDER BY `neworder`