Ваша проблема в том, что вы пытаетесь логически сравнить значения, содержащиеся в разных строках.В одной строке не может быть мета-ключа, который является и «газетным_титлом», и «статьей-субъектом».Если вы измените И на ИЛИ, то вы получите записи, которые являются или не совпадают.
Я думаю, что решение здесь состоит в том, чтобы использовать сводную таблицу для мета значений.Идея здесь состоит в том, чтобы объединить информацию, содержащуюся в нескольких строках, в одну строку для каждого post_id, а затем в целевом объекте where, где все столбцы имеют значение 1. Я в качестве примера собрал скрипт, основанный на информации, которую вы 'мы предоставили:
Пожалуйста, убедитесь, что этот скрипт запущен в тестовой среде и не конфликтует с вашими существующими данными
create table wp.posts (post_id int, description varchar(25), post_date date);
create table wp.meta (post_id int, meta_key varchar(15), meta_value varchar(25));
-- Setup post records
insert into wp.posts values
(1, 'Post #1', MAKEDATE(2011, 5)), (2, 'Post #2', MAKEDATE(2011, 8)),
(3, 'Post #3', MAKEDATE(2011, 30)), (4, 'Post #4', MAKEDATE(2011, 5)),
(5, 'Post #5', MAKEDATE(2011, 7)), (6, 'Post #6', MAKEDATE(2011, 2));
-- Setup meta data for post records
insert into wp.meta values
(1, 'newspaper_title', 'NY Post'), (2, 'newspaper_title', 'NY Post'),
(1, 'day', 'Monday'), (2, 'day', 'Wednesday'),
(1, 'article_subject', 'Local'), (2, 'article_subject', 'Politics'),
(3, 'newspaper_title', 'The Times'), (4, 'newspaper_title', 'The Times'),
(3, 'day', 'Friday'), (4, 'day', 'Tuesday'),
(3, 'article_subject', 'Politics'), (4, 'article_subject', 'Politics'),
(5, 'newspaper_title', 'The Herald'), (6, 'newspaper_title', 'Daily Tribune'),
(5, 'day', 'Sunday'), (6, 'day', 'Wednesday'),
(5, 'article_subject', 'Arts'), (6, 'article_subject', 'Local');
-- Show all the data
SELECT p.description, p.post_date, meta_key, meta_value
FROM wp.posts p JOIN wp.meta m ON (p.post_id = m.post_id)
ORDER BY p.post_id;
-- Search based on newspaper_title = 'The Times' AND article_subject = 'Politics'
SELECT p.*
FROM wp.posts p
JOIN
(
SELECT post_id,
max(CASE WHEN (meta_key = 'newspaper_title' AND meta_value = 'The Times')
THEN 1 ELSE 0 END) targetNewspaper,
max(CASE WHEN (meta_key = 'article_subject' AND meta_value = 'Politics')
THEN 1 ELSE 0 END) targetSubject
FROM wp.meta
GROUP BY post_id
) m
ON (p.post_id = m.post_id)
WHERE targetNewspaper = 1 AND targetSubject = 1
ORDER BY p.post_date;
Последний запрос в скрипте - этотот, который вы после.С тестовым набором данных он возвращает:
post_id description post_date
----------- ------------------------- -------------------------
4 Post #4 2011-01-05
3 Post #3 2011-01-30
Для каждого атрибута, который необходимо проверить, вы добавили бы дополнительный оператор case, как показано выше в мета-запросе, и добавили к предложению where условие, чтобы проверить, является ли онобыл найден.(т.е. newTargetedValue = 1)
Обновление на основе комментария OP:
По моему мнению, метод оценки или подсчета не так гибок, как использование сводной таблицы.Внутренняя / сводная таблица, по сути, устанавливает флаги для атрибутов, которые соответствуют на основе предоставленных вами случаев.(Значение будет 1 или 0). В вашем текущем примере вы просто складываете И все вместе, так что все должно быть установлено, чтобы можно было использовать счет или счет.Если позже вам потребовалось логически сравнить эти атрибуты для более сложного поиска, счет / оценка больше не работает.Я попытаюсь объяснить на примере.
Скажем, я попросил вас добавить в результаты поиска, которые вы уже предоставили в вопросе, где я хочу, чтобы все сообщения, которые имели мета-значение "день" =«Воскресенье» независимо от газеты.Короче говоря, я хочу:
- Все «политические» колонки из «The Times».
- Вместе со всеми сообщениями, которые произошли в «воскресенье» (независимо от того, какая газета былаin)
Это не сработает со счетом / счетом, потому что совпадающие строки могут возвращать 1, 2 или 3 строки в зависимости от количества совпадающих атрибутов.
- Количество = 1 (т. Е. Только атрибут статей в воскресных публикациях)
- Количество = 2 Любые 2 совпадающих атрибута (т. Е. Воскресные сообщения и статьи о политике)
- Количество= 3 Соответствует всем критериям (например, статья о политике в воскресном выпуске «The Times»)
С помощью сводной таблицы вы все равно можете использовать логические выражения: (включая мета-флаги для ясности)
SELECT p.*, m.targetNewspaper, targetSubject, targetDay
FROM wp.posts p
JOIN
(
SELECT post_id,
max(CASE WHEN (meta_key = 'newspaper_title' AND meta_value = 'The Times')
THEN 1 ELSE 0 END) targetNewspaper,
max(CASE WHEN (meta_key = 'article_subject' AND meta_value = 'Politics')
THEN 1 ELSE 0 END) targetSubject,
max(CASE WHEN (meta_key = 'day' AND meta_value = 'Sunday')
THEN 1 ELSE 0 END) targetDay
FROM wp.meta
GROUP BY post_id
) m
ON (p.post_id = m.post_id)
WHERE (targetNewspaper = 1 AND targetSubject = 1) OR targetDay = 1
ORDER BY p.post_date;
Вот результаты:
post_id description post_date targetNewspaper targetSubject targetDay
-------- ------------- ----------- ----------------- --------------- -----------
4 Post #4 2011-01-05 1 1 0
5 Post #5 2011-01-07 0 0 1
3 Post #3 2011-01-30 1 1 0
Да, это выглядит несколько сложно, но как только у вас есть первоначальная идея, это довольно просто относительно того, как вы собираетесь добавлять больше целей поискаи как логически сравнить их, чтобы получить записи, которые вы ищете.
Надеюсь, что это объяснение сделало вещи немного более удобочитаемыми.