Interroger plusieurs valeurs de métadonnées?

22

Comment rechercher plusieurs valeurs de méta clé avec la même clé

$querystr = "  
            SELECT $wpdb->posts.* 
            FROM $wpdb->posts, $wpdb->postmeta
            WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 

            AND $wpdb->postmeta.meta_key = 'key1'   
            AND $wpdb->postmeta.meta_value = 'value1'
            // why doesn't this work?
            AND $wpdb->postmeta.meta_value = 'value2'

            AND $wpdb->posts.post_status = 'publish' 
            AND $wpdb->posts.post_type = 'post'
            ORDER BY $wpdb->posts.post_date DESC
                ";

code suivant

<?php 
$args = array(
    'meta_query' => array(
        array(
            'key' => 'key1',
            'value' => 'value1',
            'compare' => '='
        ),
// this array results in no return for both arrays
        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);
$the_query  = new WP_Query( $args );
 ?>

                <?php /* Start the Loop */ ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

                    <?php get_template_part( 'content', get_post_format() ); ?>

                <?php endwhile; ?>
steen
la source

Réponses:

31

J'ai l'impression qu'il y a une confusion ET / OU ici.

Les requêtes dans l'OP ne renverront que les publications qui ont à la fois key1 = 'value1' ET key2 = 'value2'. La plupart des plugins WP (que je sache, de toute façon) ne stockent pas plusieurs valeurs dans postmeta, pour le même message, en utilisant la même clé.

Si ce que vous voulez est vraiment un OU (vous voulez obtenir les messages où key1 = 'value1', ainsi que les messages où key1 = 'value2'), alors voir la réponse de @ WhiskerSandwich, en utilisant 'IN' et un tableau de valeurs pour le paramètre de valeur.

Alternativement, vous pouvez fournir un relationparamètre à `meta_query ':

$args = array(
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'key1',
            'value' => 'value1',
            'compare' => '='
        ),

        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);

Notez que l'utilisation de OR comme relation pour plusieurs méta-requêtes utilisant la même clé est l'équivalent fonctionnel de l'utilisation INet d'un tableau de valeurs pour une seule.

Gorges de Boone
la source
Merci pour cela, Boone. Je ne savais pas que le param "relation" existait. M'a aidé.
MathSmath
Cela fonctionne si vous n'avez qu'une seule clé pour effectuer une recherche. Si vous en avez deux ou plus, vous devrez peut-être utiliser 'ET' pour les combiner dans le paramètre de relation, auquel cas la réponse de @ WhiskerSandwich ci-dessous est la meilleure solution.
SinisterBeard
14

J'ai eu le même problème lorsque le passage de plusieurs tableaux pour la même clé ne fonctionnait pas. À la place, utilisez simplement un tableau, définissez «valeur» sur un tableau de valeurs et définissez «comparer» sur IN:

<?php

$args = array(
    'meta_query' => array(
        array(
            'key' => 'key1',
            'value' => array('value1', 'value2'),
            'compare' => 'IN'
        ),
    )
);
$query = new WP_Query( $args );

?>
WhiskerSandwich
la source
1

Vous devez alias la table postmeta pour la deuxième valeur:

$querystr = "  
        SELECT $wpdb->posts.* 
        FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
        WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 

        AND $wpdb->postmeta.meta_key = 'key1'   
        AND $wpdb->postmeta.meta_value = 'value1'
        AND mt1.meta_key = 'key1'
        AND mt1.meta_value = 'value2'

        AND $wpdb->posts.post_status = 'publish' 
        AND $wpdb->posts.post_type = 'post'
        ORDER BY $wpdb->posts.post_date DESC
            ";

Vous pouvez également le faire maintenant depuis la 3.1 avec un meta_query:

$args = array(
    'meta_query' => array(
        array(
            'key' => 'key1',
            'value' => 'value1',
            'compare' => '='
        ),
        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);
$query = new WP_Query( $args );
Milo
la source
Salut Milo merci d'avoir répondu. Le SQL ne renvoie aucune valeur. Et le tableau ne renvoie également aucune valeur, sauf si je supprime la deuxième clé et la valeur du tableau. Est-ce donc un bug?
steen
@steen - Je ne sais pas quel est votre problème, j'ai testé les deux méthodes et elles fonctionnent dans mon installation de 3.3.1. Votre clé est-elle littéralement «clé1» et les valeurs «valeur1» et «valeur2»? Ne voyez-vous rien si vous print_r( $the_query );immédiatement après la requête?
Milo
0

La clé est la clé1 et les valeurs «valeur1» et «valeur2» l'ont essayé à la fois en texte et en numérique dans une nouvelle installation avec vingt-onze. print_r ($ the_query); la sortie des travaux semble normale. Également essayé key1 et key2 ne fonctionne pas non plus. Cela fonctionne dès que je le limite à un seul tableau. Vérifié avec différents navigateurs.

Cela fonctionne cependant.

    <?php 
$args = array(
    'meta_query' => array(
        array(
            'key' => 'wtf',
            'value' => '1',
            'compare' => '>='
        ),
// this array results in no return for both arrays
        array(
            'key' => 'wtf',
            'value' => '2',
            'compare' => '<='
        )
    )
);
$the_query  = new WP_Query( $args );

 ?>
steen
la source