¿Cómo contar cuántas veces aparece un meta_valor en una columna por cierta meta_clave?

8 minutos de lectura

avatar de usuario
ionut

Estoy tratando de consultar cuántas veces existe cada registro en una columna de mi tabla desde la base de datos en WordPress y exportar esa columna. ¿Cómo haría esto?

En el Excel exportado, quiero tener la columna de meta_value con meta_key “user_valid” y una columna con el recuento de cuántas veces existe ese meta_value en la columna mysql.

meta_key          meta_value

user_valid        '1, 2, 3'      
user_valid        '1, 2, 1' 
user_valid        '1, 2, 3'

Para exportar la columna ‘meta_value’ con meta_key ‘user_valid’ utilicé:

SELECT meta_value FROM `us_test` WHERE meta_key = 'user_valid'

Y exporto con el botón exportar de MYSQL después de usar esta consulta.

No sé cómo hacer la consulta para la otra columna.

Creo que debería ser algo como esto, pero no estoy seguro, porque cuando uso la siguiente consulta, no devuelve todos los registros:

SELECT meta_value, COUNT( * ) c FROM `us_test` WHERE meta_key = 'user_valid' GROUP BY meta_value

  • Estoy confundido … ¿te estás dando una recompensa por una respuesta “ejemplar”? ¿O estás buscando una alternativa?

    – rnevio

    14 de noviembre de 2015 a las 2:46

  • @rnevius Creo que OP eligió la explicación de recompensa incorrecta. Hay mejores formas de hacer esto, así que creo que necesita respuestas con estas alternativas.

    – Pieter Goosen

    14 de noviembre de 2015 a las 4:19

Tiene dos opciones aquí, la forma de WordPress y la otra forma, SQL.

Justo antes de comenzar, nunca debe codificar un nombre de base de datos, el problema es que necesitaría cambiar el nombre de la base de datos en todas las consultas donde está codificada en caso de que mueva el código a otro sitio web con un nombre de base de datos diferente, también cuando cambie el nombre de la base de datos en el sitio en el que está trabajando. Esto puede ponerte en una persecución inútil si te olvidas de eso.

Debería siempre siempre desinfecte y valide los datos de entrada para garantizar que sea seguro evitar que se inyecte cualquier código malicioso en su sitio. La inyección de SQL es común y muchos piratas informáticos usan la inyección de SQL para piratear un sitio.

sql

SQL le da a uno un poco menos de control ya que es menos dinámico. Por ejemplo, si necesita obtener un recuento solo para un determinado término, deberá modificar la consulta directamente o deberá implementar algún tipo de sistema de filtro.

Como he dicho, nunca codifique los nombres de la base de datos, utilice la clase wpdb para establecer el prefijo. Esto evitará problemas en el futuro. Además, como dije, debe desinfectar para evitar la inyección de SQL, en este caso, usaremos el prepare método de la clase wpdb para cuidar el saneamiento y protegerá contra la inyección de SQL.

Aquí está la función, que he comentado aquí y allá para que tenga sentido:

function get_post_meta_key_count( $key = '', $value="", $type="post", $status="publish" ) 
{
    // Use $wpdb to avoid bugs and errors, do not hardcode db names
    global $wpdb;

    if( empty( $key ) )
        return;


    // Set the default WHERE clause where we return the count of the key regardless of value
    $where = $wpdb->prepare( 
        "
            pm.meta_key = '%s' 
            AND p.post_type="%s" 
            AND p.post_status="%s"
        ", 
        $key, 
        $type, 
        $status 
    );

    // If a value is specified, add that to the WHERE clause
    if ( $value ) {
        $where .= $wpdb->prepare( 
            "
                AND pm.meta_value="%s"
            ", 
            $value 
        );
    }

    // Query the db to return the post count according to key and value if value is set
    $count = $wpdb->get_var(
        "
            SELECT count(DISTINCT pm.post_id)
            FROM {$wpdb->postmeta} pm
            JOIN {$wpdb->posts} p ON (p.ID = pm.post_id)
            WHERE {$where}
        "
    );

    return $count;
}

Lo que he hecho aquí es establecer un parámetro si alguna vez necesita obtener el recuento de un valor meta específico de una clave meta específica.

USO

Ahora puede usar la función de la siguiente manera:

  • echo get_post_meta_key_count( 'my_key' ); para el conteo de publicaciones de meta_key my_key para el tipo de publicación predeterminada post y solo publicaciones publicadas

  • echo get_post_meta_key_count( 'my_key', '', 'custom_post_type', 'trash' ); para el conteo de publicaciones de meta_key my_key para el tipo de publicación personalizada custom_post_type y solo publicaciones descartadas

  • echo get_post_meta_key_count( 'my_key', 'my_value' ); para el conteo de publicaciones de meta_key my_key y para el meta_value, my_value para el tipo de publicación predeterminada post y solo publicaciones publicadas

WP_Query

Si está buscando una forma de compilación para hacer esto (que siempre debe ser tu primera opción), puede utilizar el WP_Query clase para hacerlo.

El problema con el uso WP_Query es que, puede resultar realmente caro si no se utiliza correctamente. Muchas personas evitan WP_Query debido a esto, o sin saberlo ejecuta consultas que son bastante costosas e innecesarias. Así que buscaré una manera de hacer esto tan rápido como una consulta SQL personalizada.

La verdadera ventaja de WP_Query encima de una consulta SQL personalizada, puede ajustar la consulta simplemente pasando los parámetros necesarios, WP_Query siempre se encargará del trabajo duro para construir la consulta SQL adecuada de acuerdo con los parámetros pasados.

Veamos cómo optimizar WP_Query para simplemente devolver un recuento de publicaciones

  • En primer lugar, solo consultaremos una sola publicación. WP_Querypor defecto, está construido de tal manera que no importa cuántas publicaciones se consulten (1, 100 o todas las publicaciones), WP_Query seguirá buscando todos publicaciones que coinciden con la consulta, aunque ya haya encontrado y devuelto la cantidad consultada de publicaciones. La razón de esto es la paginación. Para calcular correctamente la paginación, WP_Query necesita saber cuántas publicaciones hay que coincidan con la consulta.

    Asi que WP_Query continúa mirando a través de la base de datos después de devolver la cantidad de publicaciones consultadas para contar todas las publicaciones que coinciden con la consulta. Este recuento de publicaciones se almacena en el $found_posts propiedad de la consulta, y es este número el que se usa junto con posts_per_page que se utiliza para calcular cuántas páginas habría.

    Esto no funciona para get_postsa pesar de que get_posts usos WP_Query. get_posts pasa 'no_found_rows' => true a WP_Query lo que rompe la consulta tan pronto como se encuentra la cantidad de publicaciones consultadas. Esto rompe legalmente la paginación, por eso get_posts son un gran dolor de cabeza para paginar correctamente

  • En segundo lugar, solo consultaremos el ID de la publicación individual que necesitamos consultar, no el completo. WP_Post objeto. Esto ahorra tiempo de consulta.

Así que veamos esta función:

function get_post_meta_key_count( $key = '', $value="", $args = [] ) 
{
    // If the $key value is empty, bail
    if( empty( $key ) )
        return;

    // Set the defaults and override any value set for the specific default
    $args['posts_per_page'] = 1;
    $args['fields']         = 'ids';

    if ( $value ) {
        $args['meta_query'][] = [
            'key'   => $key,
            'value' => $value
        ];
    } else {
        $args['meta_query'][] = [
            'key' => $key,
        ];
    }
    $q = new WP_Query( $args );

    // Return the post count
    return $q->found_posts;
}

USO

WP_Querypor defecto, utiliza el post tipo de publicación y publish como estado de la publicación, por lo que no es necesario configurarlo para las publicaciones publicadas normales. He incluido un tercer parámetro aquí llamado $argseste parámetro acepta exactamente los mismos parámetros que el WP_Query clase ya que todos estos se pasan directamente a WP_Query. Por lo tanto, puede agregar cualquier parámetro aquí para obtener un recuento de una meta clave o valor específico

  • echo get_post_meta_key_count( 'my_key' ); para el conteo de publicaciones de meta_key my_key para el tipo de publicación predeterminada post y solo publicaciones publicadas

  • echo get_post_meta_key_count( 'my_key', 'my_value' ); para el conteo de publicaciones de meta_key my_key y para el meta_value, my_value para el tipo de publicación predeterminada post y solo publicaciones publicadas

  • echo get_post_meta_key_count( 'my_key', 'my_value', ['post_type'=>'cpt', 'cat'=>1] ); para el conteo de publicaciones de meta_key my_key y para el meta_value, my_value para el tipo de publicación personalizada cpt y solo publicaciones publicadas del ID de categoría 1

PRUEBAS DE RENDIMIENTO EN meta_key con 24 publicaciones

  • sql -> 1 consulta en +/- 0.005 segundos

  • WP_Query -> 2 consultas en +/- 0.012 segundos

Como puede ver, hay una diferencia mínima en el rendimiento, por lo que el WP_Query El método será fácilmente la mejor opción aquí, ya que es mucho más dinámico, aunque solo un poco más lento.

Entonces, responderé mi propia pregunta:

La consulta de mi pregunta es absolutamente correcta:

SELECT meta_value, COUNT( * ) c FROM `us_test` WHERE meta_key = 'user_valid' GROUP BY meta_value

¿Ha sido útil esta solución?