Вековой вопрос (# 1, # 2Я все еще борюсь с проблемой. Теперь попробуем с помощью простого SQL-запроса:
global $wpbd;
$post_table = $wpdb->prefix . 'posts';
$meta_table = $wpdb->prefix . 'postmeta';
$fs_query = "SELECT $post_table.ID
FROM $post_table
INNER JOIN $meta_table
ON ( $post_table.ID = $meta_table.post_id )
WHERE 1=1
AND $post_table.post_type = 'services'
AND $post_table.post_status = 'publish'
AND (
$meta_table.meta_key = 'example_featured'
AND $meta_table.meta_value = 1
)
AND $meta_table.meta_key = 'example_sort'
GROUP BY $post_table.ID
ORDER BY $meta_table.meta_value+0 ASC
LIMIT 0, 8";
my_var_dump($fs_query);
+------------+--------------+----------------+ | ID | post_type | post_status | + ------------ + -------------- + ---------------- + | 1 | услуги | опубликовать | + ------------ + -------------- + ---------------- +
+------------+------------+------------------+--------------+ | ID | post_id | meta_key | meta_value | + ------------ + ------------ + ------------------ + ---- ---------- + | 1 | 1 | example_featured | 1 | | 2 | 1 | пример_сортировка | 5 | + ------------ + ------------ + ------------------ + ---- ---------- +
Борьба с созданием этого запроса SQL:
Я хочу, чтобы все post_id где post_type
= ‘услуги’ и post_status
= ‘опубликовать’ и значение для ассоциированного meta_value
(example_featured
) равен 1 (одному). А затем хотите отсортировать результат, используя другое мета-значение, которое я передал, используя другой meta_key
(example_sort
). Если я удалю AND $meta_table.meta_key = 'example_sort'
из запроса тогда получите те идентификаторы постов, но с запросом выше я ничего не получаю вообще.
Как мне это сделать?
Вы уже делаете group by
, так что вы можете подойти к этому с помощью условного агрегирования. Это означает перемещение некоторых условий в having
пункт. Я также ввел псевдонимы таблиц — они облегчают написание и чтение запросов:
SELECT p.ID
FROM $post_table p INNER JOIN
$meta_table m
ON (p.ID = m.post_id )
WHERE p.post_type = 'services' AND
p.post_status = 'publish'
GROUP BY p.ID
HAVING SUM(m.meta_key = 'example_featured' AND m.meta_value = 1) > 0
ORDER BY MAX(CASE WHEN m.meta_key = 'example_sort' then m.meta_value end)
LIMIT 0, 8;
Это пример запроса набора внутри наборов, то есть вы смотрите на логику для всех мета-ключей для данного поста. Логика состоит из двух частей: фильтрующей части (в «example_featured») и упорядочивающей части (в «example_sort»). Проблема, с которой вы столкнулись, заключается в том, что эта информация находится в двух разных строках в мета-таблице.
HAVING
Предложение подсчитывает количество строк, которые удовлетворяют условию «example_featured». Если они встречаются, SUM()
больше 0. В качестве отступления, если вы хотите гарантировать, что значение было никогда там, то вы бы использовали = 0
скорее, чем > 0
,
ORDER BY
Предложение извлекает значение из строки, где ключом является «example_sort». Если найдено более одного совпадения, используется максимальное значение. Если совпадений нет, то результат MAX()
выражение NULL
и отсортировано соответственно.
Других решений пока нет …