SELECT max(meta_value) FROM wp_postmeta WHERE meta_key='price'... deja de funcionar cuando el valor supera 999

11 jun 2012, 08:19:02
Vistas: 14.7K
Votos: 6

Resumen: No estoy intentando devolver un post. Solo quiero el valor más alto para un meta_value específico entre todos los posts... solo el valor en sí.

Detalles: He añadido un meta_key personalizado "price" a todos mis posts. El valor siempre es un entero (sin decimales o caracteres no numéricos). Estoy intentando hacer una consulta que devuelva el valor meta_value más alto asociado con este meta_key.

Código con Problemas

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;
}

Resultados Erróneos: Al principio pensé que el código anterior funcionaba, porque lo hace si todos los meta_values son menores que 999. Pero descubrí que si el meta_value es mayor que 999, entonces es ignorado. Así que en realidad el código anterior me da el max(meta_value) solo para valores menores que 1000.

Solicitud a la Comunidad: Obviamente no sé por qué falla, pero tengo la sensación de que tiene que ver con cómo WP almacena el valor - ¿quizás es algo relacionado con el tipo de dato? O tal vez no debería usar $wpdb->get_var(). Cualquier orientación será muy apreciada.

0
Todas las respuestas a la pregunta 4
1
16

El meta_value no es de tipo entero para que max devuelva valores correctos. Puedes usar el método cast de MySQL para convertirlo a enteros de la siguiente manera:

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

11 jun 2012 08:51:28
Comentarios

Incluyendo solo publicaciones publicadas: http://pastebin.com/pR6SDEdf

emc emc
16 may 2013 02:24:50
1

Modifiqué la función original y la solución de KDM para tener una función más universal. Queda así:

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 );
}

De esta manera puedes obtener tanto los valores mínimos como máximos de cualquier meta_value personalizado. También cambié wp_postmeta por $wpdb->postmeta para adaptarse a cualquier prefijo que uses.

Nota: Si deseas consultar un dígito, reemplaza %s en la declaración $wpdb->prepare() con %d.

21 may 2013 03:05:10
Comentarios

Gracias por tu respuesta. Recibo un error de sintaxis SQL. El problema es que wpdb->prepare envuelve la variable $end con '', por lo que la consulta queda como SELECT 'max'(cast... y eso genera un error. Puedes concatenarlo como $sql = "SELECT " . $end . "(cast...". Eso funcionó para mí.

Laxmana Laxmana
6 may 2014 17:29:05
0

Modifiqué la solución de szajmon para que funcione con wp_cache y corregir el error de sintaxis SQL que obtenía.

wpdb->prepare envuelve la variable $end entre comillas y eso genera un error (al menos en mi caso)

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 may 2014 17:42:31
0

Aquí hay una forma poco elegante en la que lo hice usando php max array y el WP_Query integrado

    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 jul 2022 23:33:36