To, czego chcesz, jest możliwe, ale wymaga zagłębiania się w SQL, którego lubię unikać, gdy tylko jest to możliwe (nie dlatego, że nie wiem, jestem zaawansowanym programistą SQL, ale dlatego, że w WordPress chcesz używać interfejsu API, gdy tylko jest to możliwe aby zminimalizować przyszłe problemy ze zgodnością związane z przyszłymi potencjalnymi zmianami struktury bazy danych).
SQL z UNIONoperatorem to możliwość
Aby użyć SQL czego potrzebujesz to UNIONoperator w zapytaniu, coś takiego zakładając kategorię ślimaki są "category-1", "category-1"i "category-3":
SELECT * FROM wp_posts WHERE ID IN (
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-1'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-2'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-3'
LIMIT 5
)
Możesz użyć SQL UNION z posts_joinfiltrem
Korzystając z powyższego, możesz po prostu bezpośrednio nawiązać połączenie lub użyć posts_joinhaka filtrującego w następujący sposób; Uwaga: Używam heredoc PHP, więc upewnij się, że SQL;pozostało kolor. Zauważ też, że użyłem globalnego var, aby umożliwić ci zdefiniowanie kategorii poza hakiem, umieszczając informacje o kategorii w tablicy. Możesz umieścić ten kod we wtyczce lub w functions.phppliku motywu :
<?php
global $top_5_for_each_category_join;
$top_5_for_each_category_join = array('category-1','category-2','category-3');
add_filter('posts_join','top_5_for_each_category_join',10,2);
function top_5_for_each_category_join($join,$query) {
global $top_5_for_each_category_join;
$unioned_selects = array();
foreach($top_5_for_each_category_join as $category) {
$unioned_selects[] =<<<SQL
SELECT object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='{$category}'
LIMIT 5
SQL;
}
$unioned_selects = implode("\n\nUNION\n\n",$unioned_selects);
return $join . " INNER JOIN ($unioned_selects) categories ON wp_posts.ID=categories.object_id " ;
}
Ale mogą wystąpić skutki uboczne
Oczywiście użycie haków do modyfikacji zapytań, jak posts_joinzawsze, wywołuje skutki uboczne, ponieważ działają one globalnie na zapytania, a zatem zwykle trzeba zawinąć modyfikacje w taki, ifktóry używa go tylko wtedy, gdy jest to potrzebne, a kryteria, które należy przetestować, mogą być trudne.
Zamiast tego skupić się na optymalizacji?
Zakładam jednak, że twoje pytanie dotyczy bardziej optymalizacji niż możliwości wykonania zapytania z 5 najlepszych czasów 3, prawda? Jeśli tak jest, to może istnieją inne opcje korzystające z interfejsu API WordPress?
Lepiej używać przejściowego interfejsu API do buforowania?
Zakładam, że twoje posty nie będą się tak często zmieniać, prawda? Co się stanie, jeśli zaakceptujesz trzy (3) trafienia kwerendy okresowo, a następnie buforujesz wyniki przy użyciu interfejsu Transients API ? Otrzymasz łatwy do utrzymania kod i doskonałą wydajność; znacznie lepiej niż UNIONpowyższe zapytanie, ponieważ WordPress przechowuje listy postów jako szeregową tablicę w jednym rekordzie wp_optionstabeli.
Możesz wziąć następujący przykład i wpaść do katalogu głównego swojej witryny, test.phpaby to przetestować:
<?php
$timeout = 4; // 4 hours
$categories = array('category-1','category-2','category-3');
include "wp-load.php";
$category_posts = get_transient('top5_posts_per_category');
if (!is_array($category_posts) || count($category_posts)==0) {
echo "Hello Every {$timeout} hours!";
$category_posts = array();
foreach($categories as $category) {
$posts = get_posts("post_type=post&numberposts=5&taxonomy=category&term={$category}");
foreach($posts as $post) {
$category_posts[$post->ID] = $post;
}
}
set_transient('top5_posts_per_category',$category_posts,60*60*$timeout);
}
header('Content-Type:text/plain');
print_r($category_posts);
Podsumowanie
Chociaż tak, możesz zrobić to, o co prosiłeś, używając UNIONzapytania SQL i posts_joinhaka filtru, ale prawdopodobnie lepiej zaoferować użycie buforowania z Transient API .
Mam nadzieję że to pomoże?