Запрос MySQL с несколькими операторами AND

Я новичок в MySQL, и у меня возникла проблема с запросом с использованием PHP. Обратите внимание на три последние строки.

$query = "
SELECT post_content, slug, ID
FROM wp_posts

INNER JOIN wp_term_relationships
ON wp_posts.ID = wp_term_relationships.object_id

INNER JOIN wp_terms
ON wp_term_relationships.term_taxonomy_id = wp_terms.term_id

INNER JOIN wp_postmeta
ON wp_posts.ID = wp_postmeta.post_id

WHERE post_status = 'publish' AND slug = 'a-slug' AND meta_key <> 'include' AND meta_key <> 'exkludera'
OR post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'include' AND meta_value = '72'
OR post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'exclude' AND meta_value <> '72'
";

Тремя последними строками я хочу сказать:

Строка 1) Выберите запрос, если он: Опубликован, Имеет ярлык и не имеет мета_ключа «включить» или «исключить»

Строка 2) Выберите запрос, если он: Опубликован, Имеет ярлык, имеет мета_ключ «включить» и мета_значение равно «72»

Строка 3) Выберите запрос, если он: Опубликован, Имеет ярлык, имеет мета_ключ «исключить» и мета_значение не равно «72».

Но это возвращает мне двойное или тройное значение каждого выбора. Его следует выбирать только в том случае, если он соответствует одному из этих трех сенариев. Что я делаю не так?


person Hakan    schedule 25.11.2011    source источник


Ответы (3)


Вам нужно использовать скобки:

WHERE (post_status = 'publish' AND slug = 'a-slug' AND meta_key <> 'include' AND meta_key <> 'exkludera')
OR (post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'include' AND meta_value = '72')
OR (post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'exclude' AND meta_value <> '72')

Простое смешивание операторов OR и AND, как в вашем примере, оценивается как true для всех случаев, когда post_status = 'publish'.

Кстати, я предполагаю, что Row 1) и т. д. относятся к строкам в вашем коде, а не к строкам, которые вы хотите вернуть из базы данных...

person jeroen    schedule 25.11.2011
comment
Я пробовал это, но никакой разницы. Да, с строкой 1, строкой 2 и строкой 3 я имею в виду последние три строки в моем примере. Пожалуйста, посмотрите еще раз. - person Hakan; 26.11.2011
comment
Возможно, есть дополнительная проблема в ваших join; вы получаете повторяющиеся строки? - person jeroen; 26.11.2011
comment
Да, у меня есть две или три повторяющиеся строки. Попробую без соединений. - person Hakan; 26.11.2011
comment
@Hakan Я не очень хорошо знаком с Wordpress, поэтому я не знаю, откуда берутся все поля, но добавление (слева ...) соединений одного за другим, вероятно, покажет вам, в чем проблема. - person jeroen; 26.11.2011

Это должно помочь заключать в скобки отдельные наборы критериев.

e.g.

$query = "
...
WHERE 
(post_status = 'publish' AND slug = 'a-slug' AND meta_key <> 'include' AND meta_key <> 'exkludera')
OR 
(post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'include' AND meta_value = '72')
OR 
(post_status = 'publish' AND slug = 'a-slug' AND meta_key = 'exclude' AND meta_value <> '72')
";

На самом деле, поскольку некоторые критерии являются общими, вы можете переписать его так:

$query = "
...
WHERE 
post_status = 'publish' AND slug = 'a-slug' AND
(
 (meta_key <> 'include' AND meta_key <> 'exkludera')
 OR 
 (meta_key = 'include' AND meta_value = '72')
 OR 
 (meta_key = 'exclude' AND meta_value <> '72')
)
";

Вы также можете использовать DISTINCT, чтобы при необходимости возвращалась только одна копия каждой записи.

SELECT DISTINCT post_content, slug, ID
person Daren Chandisingh    schedule 25.11.2011
comment
Не slove мою проблему, но очень хорошо знать! Спасибо! Я нашел проблему, последние три строки работают без соединений. Значит, что-то в них есть... - person Hakan; 26.11.2011

У меня была такая же проблема.

Я считаю, что проблема в том, что вы не упаковываете свой OR при объединении их с AND, которые вы используете. При использовании ИЛИ и И вместе они должны быть заключены в круглые скобки "()", иначе возникнет конфликт.

Вот ссылка, показывающая пример и хорошо написанные описания того, как это работает: http://www.w3schools.com/sql/sql_and_or.asp

person JoshG    schedule 25.11.2011