Old answer (which no longer works):
使用MySQL的一种偷偷摸摸的方法是,假设数字总是在末尾,将标题反转,将其转换为数字(
+0
), 然后再次反转并将其转换为数字:
function wpse174646_posts_orderby( $orderby, $query ) {
if ( $query->get( \'orderby\' ) != \'title_number\' ) return $orderby;
global $wpdb;
return \'REVERSE(REVERSE(TRIM(\' . $wpdb->posts . \'.post_title))+0)+0 \' . $query->get( \'order\' );
}
$args = array( \'orderby\' => \'title_number\', \'order\' => \'ASC\' );
add_filter( \'posts_orderby\', \'wpse174646_posts_orderby\', 10, 2 );
$query = new WP_Query( $args );
remove_filter( \'posts_orderby\', \'wpse174646_posts_orderby\', 10 );
New answer:
一种可靠(希望如此)的方法是使用我在stackexchange上发布的答案(
https://stackoverflow.com/a/28808798/664741), 一个简化的非udf版本的@plaix/richardtoth/lukehoggett的最佳响应,它将(第一次遇到的)数字填充为零:
add_filter( \'posts_clauses\', function ( $pieces, $query ) {
if ( $query->get( \'orderby\' ) != \'title_number\' ) return $pieces;
global $wpdb;
$field = $wpdb->posts . \'.post_title\';
$pieces[ \'fields\' ] .= $wpdb->prepare(
\', LEAST(\' . implode( \',\', array_fill( 0, 10, \'IFNULL(NULLIF(LOCATE(%s, \' . $field . \'), 0), ~0)\' ) )
. \') AS first_int\',
\'0\', \'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\'
);
$pieces[ \'orderby\' ] = $wpdb->prepare(
\'IF(first_int = ~0, \' . $field . \', CONCAT(\'
. \'SUBSTR(\' . $field . \', 1, first_int - 1),\'
. \'LPAD(CAST(SUBSTR(\' . $field . \', first_int) AS UNSIGNED), LENGTH(~0), %s),\'
. \'SUBSTR(\' . $field . \', first_int + LENGTH(CAST(SUBSTR(\' . $field . \', first_int) AS UNSIGNED)))\'
. \')) \' . $query->get( \'order\' )
, 0
);
return $pieces;
}, 10, 2 );
$args = array( \'orderby\' => \'title_number\', \'order\' => \'ASC\' );
$query = new WP_Query( $args );