SELECT max(meta_value) FROM wp_postmeta WHERE meta_key='price'... перестает работать, когда значение превышает 999

11 июн. 2012 г., 08:19:02
Просмотры: 14.7K
Голосов: 6

Обзор: Я не пытаюсь вернуть пост. Мне нужно просто получить единственное наибольшее значение для конкретного 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(). Любая помощь будет очень ценна.

0
Все ответы на вопрос 4
1
16

meta_value не является целочисленным типом для корректного возврата значений функцией max. Вы можете использовать метод cast в MySQL для преобразования в целые числа следующим образом:

SELECT max(cast(meta_value as unsigned)) FROM wp_postmeta WHERE meta_key='price'

11 июн. 2012 г. 08:51:28
Комментарии

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

emc emc
16 мая 2013 г. 02:24:50
1

Я модифицировал оригинальную функцию и решение 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.

21 мая 2013 г. 03:05:10
Комментарии

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

Laxmana Laxmana
6 мая 2014 г. 17:29:05
0

Я модифицировал решение 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;
}
6 мая 2014 г. 17:42:31
0

Вот неуклюжий способ, которым я это сделал, используя 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) ; 

    }
28 июл. 2022 г. 23:33:36