SELECT max(meta_value) FROM wp_postmeta WHERE meta_key='price'... перестает работать, когда значение превышает 999
Обзор: Я не пытаюсь вернуть пост. Мне нужно просто получить единственное наибольшее значение для конкретного meta_value среди всех постов... только само значение.
Подробности: Я добавил пользовательское метаполе "price" ко всем своим постам. Значение всегда целое число (без десятичных знаков или нечисловых символов). Я пытаюсь сделать запрос, который возвращает наибольшее/максимальное значение meta_value, связанное с этим конкретным meta_key.
Проблемный код
function max_meta_value(){
global $wpdb;
$query = "SELECT max(meta_value) FROM wp_postmeta WHERE meta_key='price'";
$the_max = $wpdb->get_var($query);
return $the_max;
}
Проблемные результаты: Сначала я думал, что этот код работает, потому что он действительно работает, если все meta_value меньше 999. Но затем я обнаружил, что если meta_value больше 999, то оно игнорируется. Таким образом, код выше фактически возвращает max(meta_value) только для значений меньше 1000.
Обращение к сообществу: Очевидно, я не понимаю, почему это не работает, но у меня есть ощущение, что проблема связана с тем, как WordPress хранит значение - возможно, это связано с типом данных? Или, может быть, я не должен использовать $wpdb->get_var(). Любая помощь будет очень ценна.

meta_value не является целочисленным типом для корректного возврата значений функцией max. Вы можете использовать метод cast
в MySQL для преобразования в целые числа следующим образом:
SELECT max(cast(meta_value as unsigned)) FROM wp_postmeta WHERE meta_key='price'

Включение только опубликованных записей: http://pastebin.com/pR6SDEdf

Я модифицировал оригинальную функцию и решение KDM, чтобы получить более универсальную функцию. Вот как она выглядит:
function end_meta_value( $end = "max", $meta )
{
global $wpdb;
$query = $wpdb->prepare(
"SELECT %s( cast( meta_value as UNSIGNED ) ) FROM {$wpdb->postmeta} WHERE meta_key='%s'",
$end,
$meta
);
return $wpdb->get_var( $query );
}
Таким образом, вы можете получить как минимальные, так и максимальные значения любого пользовательского meta_value.
Я также заменил wp_postmeta
на $wpdb->postmeta
, чтобы функция работала с любым префиксом, который вы используете.
Примечание: Если вам нужно запросить цифру, замените %s
в выражении $wpdb->prepare()
на %d
.

Спасибо за ответ. У меня возникает синтаксическая ошибка SQL. Проблема в том, что wpdb->prepare оборачивает переменную $end в '', поэтому запрос получается вида SELECT 'max'(cast..., что вызывает ошибку. Можно соединить строку так: $sql = "SELECT " . $end . "(cast...". У меня это сработало.

Я модифицировал решение szajmon, чтобы оно работало с wp_cache и исправил синтаксическую ошибку в SQL, которую я получил.
wpdb->prepare оборачивает переменную $end в кавычки, что вызывает ошибку (по крайней мере, в моем случае)
function get_min_max_meta_value( $type = 'max', $key ){
global $wpdb;
$cash_key = md5($key . $type);
$results = wp_cache_get($key);
if($results === false){
$sql = "SELECT " . $type . "( cast( meta_value as UNSIGNED ) ) FROM {$wpdb->postmeta} WHERE meta_key='%s'";
$query = $wpdb->prepare( $sql, $key);
return $wpdb->get_var( $query );
}
return $results;
}

Вот неуклюжий способ, которым я это сделал, используя php max array и встроенный WP_Query
function get_max_post_meta_value($category_id) {
$args = array(
'post_type' => 'cpt-name',
'post_status' => 'publish',
'cat' => $category_id,
'posts_per_page' => 1000,
);
$max_meta_value_array = array();
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
array_push($max_meta_value_array, get_post_meta( get_the_ID(), 'post_meta_name', true) );
endwhile;
wp_reset_postdata();
return max($max_meta_value_array) ;
}
