Проблема в том, что WordPress добавляет INNER JOIN
в таблицу wp_postmeta
, как только вы упоминаете meta_key
в своих условиях. Один из способов обойти проблему — добавить фильтр к предложению order by
, примерно так:
function so_orderby_priority($original_orderby_statement) {
global $wpdb;
return "(SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = 'priority') ASC";
}
add_filter('posts_orderby', 'so_orderby_priority');
query_posts(
array(
'tag' => $pagetag,
'paged' => get_query_var('paged')
)
);
remove_filter('posts_orderby', 'so_orderby_priority');
Примечание. MySQL сначала сортирует значения NULL. Если вы хотите, чтобы они сортировались последними, попробуйте что-то вроде этого (при условии, что все ваши приоритеты стоят перед ZZZZZ в алфавитном порядке):
function so_orderby_priority($original_orderby_statement) {
global $wpdb;
return "IFNULL(
(SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = 'priority'),
'ZZZZZ') ASC";
}
Изменить
Вот еще немного пояснений, предполагающих, что вы хотя бы немного понимаете SQL.
Ваш исходный query_posts
привел к следующему запросу к базе данных:
SELECT wp_posts.*
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
INNER JOIN wp_postmeta ON ( wp_posts.id = wp_postmeta.post_id )
WHERE 1 = 1
AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
AND ( wp_postmeta.meta_key = 'priority' )
GROUP BY wp_posts.id
ORDER BY wp_postmeta.meta_value ASC
LIMIT 0, 10;
Именно INNER JOIN wp_postmeta
удалил из результатов все сообщения без приоритета.
Удаление условий, связанных с meta_*
, из query_posts
:
query_posts(
array(
'tag' => $pagetag,
'paged' => get_query_var('paged')
)
);
решил эту проблему, но порядок сортировки по-прежнему неправильный. Новый SQL
SELECT wp_posts.*
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
WHERE 1 = 1
AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
GROUP BY wp_posts.id
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10;
Фильтр posts_orderby
позволяет нам изменить предложение ORDER BY
: wp_posts.post_date DESC
заменяется тем, что возвращает фильтр. Окончательный SQL становится:
SELECT wp_posts.*
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
WHERE 1 = 1
AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
GROUP BY wp_posts.id
ORDER BY (SELECT wp_postmeta.meta_value
FROM wp_postmeta
WHERE wp_posts.id = wp_postmeta.post_id
AND wp_postmeta.meta_key = 'priority') ASC
LIMIT 0, 10
который делает то, что вам нужно.
person
Hobo
schedule
03.07.2012