Wordpress - getting all values for a custom field key (cross-post)

One possible approach would be to use one of the helper methods in the WPDB class to do a more refined meta based query. The caveat to using some of these functions however, is that you don't usually get back a simple array of data and usually have to make needless references to object properties, even if you're only calling for one column or row.

Of course, not all functions are the one and the same, and a purposeful mention goes out to the WPDB method, get_col which returns a simple flat array of the data queried for, i make this mention specifically because the example following will call upon this method.

WordPress - WPDB Selecting a column of data
$wpdb->get_col()

Here's an example function which queries the database for all posts of a chosen post type, post status and with a specific meta key(or custom field to the less technically minded).

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

So for example, if you like to find out which posts have a meta key of rating, for the post type movies and you'd like to store that information inside a variable, an example of such a call would be..

$movie_ratings = get_meta_values( 'rating', 'movies' );

If you wanted to do nothing more than print that data to screen, PHP's implode function can quickly splice that simple array into lines of data.

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

You can also use the returned data to work out how many posts have these meta values by doing a simple loop over the returned data and building an array of the counts, for example.

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

This logic could be applied to various kinds of data, and extended to work any number of different ways. So i hope my examples have been helpful and simple enough to follow.


I'd just like to add one tiny thing to t31os's code above. I changed "SELECT" into "SELECT DISTINCT" to eliminate duplicate entries when I used this code myself.


It is not good or needed to use the global $wpdb:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );

Tags:

Custom Field