Запрос нескольких значений мета-ключей?

27 янв. 2012 г., 05:44:36
Просмотры: 105K
Голосов: 26

Как запросить несколько значений мета-ключей с одинаковым ключом

$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'
            // почему это не работает?
            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
                ";

следующий код

<?php 
$args = array(
    'meta_query' => array(
        array(
            'key' => 'key1',
            'value' => 'value1',
            'compare' => '='
        ),
// этот массив приводит к отсутствию результатов для обоих массивов
        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);
$the_query  = new WP_Query( $args );
 ?>

                <?php /* Начало цикла */ ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

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

                <?php endwhile; ?>
0
Все ответы на вопрос 4
2
34

Мне кажется, здесь происходит путаница между И/ИЛИ.

Запросы в исходном сообщении будут возвращать только записи, у которых одновременно key1 = 'value1' И key2 = 'value2'. Большинство плагинов WordPress (по крайней мере, из тех, что я знаю) не хранят несколько значений в postmeta для одной и той же записи с одним и тем же ключом.

Если вам действительно нужно условие ИЛИ (то есть вы хотите получить записи, где key1 = 'value1', а также записи, где key1 = 'value2'), тогда смотрите ответ @WhiskerSandwich с использованием 'IN' и массива значений для параметра value.

Альтернативно, вы можете указать параметр relation в `meta_query':

$args = array(
    'meta_query' => array(
        'relation' => 'OR', // тип связи между условиями (ИЛИ)
        array(
            'key' => 'key1',    // ключ метаполя
            'value' => 'value1', // значение для сравнения
            'compare' => '='     // оператор сравнения
        ),
        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);

Обратите внимание, что использование OR в качестве связи для нескольких метазапросов с одним и тем же ключом функционально эквивалентно использованию IN с массивом значений для одного запроса.

13 мар. 2012 г. 21:07:10
Комментарии

Спасибо, Boone. Я не знал о существовании параметра "relation". Очень помогло.

MathSmath MathSmath
22 мар. 2012 г. 00:37:45

Это работает, если у вас только один ключ для поиска. Если у вас два или более ключа, возможно, потребуется использовать 'AND' для их объединения в параметре relationship, и в этом случае ответ @WhiskerSandwich ниже подойдет лучше.

SinisterBeard SinisterBeard
21 апр. 2015 г. 14:58:54
0
15

У меня была такая же проблема, когда передача нескольких массивов для одного ключа не работала. Вместо этого просто используйте один массив, установите 'value' в массив значений и 'compare' в IN:

<?php

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

?>
13 мар. 2012 г. 20:48:28
2

Вам необходимо создать алиас для таблицы postmeta для второго значения:

$querystr = "  
        SELECT $wpdb->posts.* 
        FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
        WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 
        AND $wpdb->posts.ID = $wpdp->mt1.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
            ";

Начиная с версии 3.1, это также можно сделать с помощью meta_query:

$args = array(
    'meta_query' => array(
        array(
            'key' => 'key1',
            'value' => 'value1',
            'compare' => '='
        ),
        array(
            'key' => 'key1',
            'value' => 'value2',
            'compare' => '='
        )
    )
);
$query = new WP_Query( $args );
27 янв. 2012 г. 06:36:28
Комментарии

Привет, Мило, спасибо за ответ. SQL-запрос не возвращает значений. И массив тоже не возвращает значений, если я не удалю второй ключ и значение из массива. Так что, это баг?

steen steen
27 янв. 2012 г. 07:48:35

@steen - Я не совсем понимаю, в чем твоя проблема. Я протестировал оба метода, и они работают в моей версии 3.3.1. Твой ключ буквально 'key1', а значения 'value1' и 'value2'? Ты ничего не видишь, если выполнишь print_r( $the_query ); сразу после запроса?

Milo Milo
27 янв. 2012 г. 08:14:48
0

Ключ key1 и значения 'value1' и 'value2' пробовал в текстовом и числовом формате на чистой установке с темой Twenty Eleven. print_r( $the_query ); работает, вывод выглядит нормально. Также пробовал ключи key1 и key2 — тоже не работает. Все начинает работать, как только ограничиваюсь одним массивом. Проверял в разных браузерах.

Однако вот этот вариант работает:

    <?php 
$args = array(
    'meta_query' => array(
        array(
            'key' => 'wtf',
            'value' => '1',
            'compare' => '>='
        ),
// этот массив приводит к отсутствию результата для обоих массивов
        array(
            'key' => 'wtf',
            'value' => '2',
            'compare' => '<='
        )
    )
);
$the_query  = new WP_Query( $args );

 ?>
27 янв. 2012 г. 12:59:37