당신이 원하는 것은 가능하지만 가능할 때마다 피하고 싶은 SQL 을 파헤쳐 야 할 것입니다. 향후 잠재적 인 데이터베이스 구조 변경과 관련된 향후 호환성 문제를 최소화합니다.)
UNION
연산자가있는 SQL 은 가능성
당신이이다 필요한 SQL을 사용하려면 UNION
, 쿼리 연산자이이 범주 슬러그 가정 같은입니다 "category-1"
, "category-1"
그리고 "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
)
posts_join
필터 와 함께 SQL UNION을 사용할 수 있습니다
위의 방법을 사용하면 직접 전화를 걸 거나 다음과 같이 필터 후크를 사용할posts_join
수 있습니다 . 참고 PHP heredoc을 사용하고 있으므로 SQL;
플러시가 왼쪽 인지 확인하십시오 . 또한 전역 변수를 사용하여 범주 슬러그를 배열로 나열하여 후크 외부의 범주를 정의 할 수 있습니다. 이 코드를 플러그인이나 테마 functions.php
파일 에 넣을 수 있습니다 .
<?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 " ;
}
그러나 부작용이있을 수 있습니다
물론 쿼리 수정 후크를 사용하는 경우 posts_join
항상 쿼리에 대해 전역 적으로 작동한다는 부작용으로 항상 부작용을 유발합니다. 따라서 필요할 if
때만 사용하고 테스트 할 기준이 까다로울 수있는 수정으로 래핑해야합니다 .
대신 최적화에 집중하십니까?
그러나 귀하의 질문 에 톱 5 시간 3 쿼리를 수행하는 것보다 최적화에 관한 것이 더 중요하다고 생각 합니까? 그렇다면 WordPress API를 사용하는 다른 옵션이 있습니까?
캐싱에 과도 API를 사용하는 것이 더 낫습니까?
귀하의 게시물이 자주 변경되지 않는다고 가정합니다. 3 개의 쿼리 적중을 주기적으로 수락 한 후 Transients API를 사용하여 결과를 캐시하면 어떻게 되나요? 유지 관리 가능한 코드와 뛰어난 성능을 얻을 수 있습니다. UNION
WordPress는 게시물 목록을 wp_options
테이블의 한 레코드에 직렬화 된 배열로 저장하기 때문에 위 의 쿼리 보다 훨씬 좋습니다 .
다음 예제를 사용하여 test.php
이를 테스트하기 위해 웹 사이트의 루트에 놓을 수 있습니다 .
<?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);
요약
예, SQL UNION
쿼리 및 posts_join
필터 후크 를 사용하여 요청한 작업을 수행 할 수 있지만 대신 Transients API로 캐싱을 사용하는 것이 좋습니다.
도움이 되었기를 바랍니다?