메타 값 또는 날짜로 주문 하시겠습니까?


10

startDate몇 가지 이벤트에서만 호출되는 사용자 정의 필드가 있습니다. post_date게시물 목록을 생성하는 데 사용할 수있는 게시물이 설정되어 있지 않은지 궁금 합니다.

// if meta_key _postmeta.startDate isn't set get the rest by posts.post_date

query_posts(
    array(
        array(
            'posts_per_page' => 10,
            'meta_key' => 'startDate',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<',
            'orderby' => 'meta_value',
            'order' => 'ASC'
        ), 
        array(
            'meta_key' => 'post_date',
            'meta_value' => date('Y-m-d'),
            'meta_compare' => '<'
        )
    )
);

post_date는 맞춤 입력란입니까?
Bainternet

기본 wordpress 게시 필드를 잘못 가정했지만 잘못되었을 수 있습니까? 어느 쪽이든 id는 기본 날짜를 사용하고 싶습니다 ...
v3nt

좋아 메타 필드가 아니라 게시물 테이블에
Bainternet

검색어 인수를 수정했습니다. 표시 한 내용이 전혀 왜곡되지 않았 으면 좋을 경우 언제든지 되 돌리십시오.
t31os

t31os를 건배합니다-더 명확하게하기 위해 다시 편집했습니다. startDate를 사용하여 NOW보다 오래된 컨텐츠를 선택해야하며 startDate가 설정되지 않은 경우 기본 게시물의 날짜 post_date를 사용하십시오.
v3nt

답변:


11

SQL로 설명 할 수 있으면 쿼리 할 수 ​​있습니다! 기본 쿼리를 변경하려는 위치는 세 곳입니다.

SELECT wp_posts.*
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND wp_postmeta.meta_key = 'startDate'
    AND CAST(wp_postmeta.meta_value AS CHAR) < '2011-03-23'
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value DESC
LIMIT 0, 10
  • 조인은 왼쪽 조인이어야합니다.
  • 어디에 절
  • 순서

은 가입하고 어디에 절을 통해 추가 기능 . 출력이 필터링되므로 다음과 같이 연결할 수 있습니다._get_meta_sql()

add_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' );
function wpse12814_get_meta_sql( $meta_sql )
{
    // Move the `meta_key` comparison in the join so it can handle posts without this meta_key
    $meta_sql['join'] = " LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate') ";
    $meta_sql['where'] = " AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '" . date('Y-m-d') . "')";
    return $meta_sql;
}

order 절은 다음을 통해 필터링됩니다 posts_orderby.

add_filter( 'posts_orderby', 'wpse12814_posts_orderby' );
function wpse12814_posts_orderby( $orderby )
{
    $orderby = 'COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC';
    return $orderby;
}

이를 통해 다음과 같은 SQL 쿼리가 제공됩니다.

SELECT wp_posts.*
FROM wp_posts
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'startDate')
WHERE 1=1
    AND wp_posts.post_type = 'post'
    AND (wp_posts.post_status = 'publish')
    AND (wp_postmeta.meta_value IS NULL OR wp_postmeta.meta_value < '2011-03-23')
GROUP BY wp_posts.ID
ORDER BY COALESCE(wp_postmeta.meta_value, wp_posts.post_date) ASC
LIMIT 0, 10

쿼리를 수행 한 후 필터를 분리해야합니다. 그렇지 않으면 다른 쿼리도 엉망이됩니다. 가능 하면 query_posts()자신을 호출하지 말고 페이지를 설정하는 동안 WordPress에서 수행하는 기본 게시물 쿼리를 수정하십시오.


2
매우 우아한 솔루션, 나는 그렇게 COALESCE를 사용하려고 생각하지 않았을 것입니다. 기본 'wp_'접두사를 가정하지 않고 {$ wpdb-> prefix}를 대신 사용하는 것이 좋습니다.
goldenapples

@goldenapples : 예, 일반화 할 수는 있지만이 쿼리에 이미 너무 구체적이므로 메타 부분으로 다른 쿼리를 엉망으로 만들므로 이것이 필요하지 않다고 생각했습니다.
Jan Fabry

고마워 얀-그것은 눈을 뜨게 오프너입니다! 여전히 워드 프레스에 관심이 있고 내 페이지에서 이것이 어디에서 호출되는지 궁금하십니까? 그리고 어떻게 '후킹 해제'합니까? 예 : // $ theQuery ... then <? php if (have_posts ()) : while (have_posts ()) : the_post (); ?>?
v3nt

@daniel : 테마 functions.php파일에 함수를 넣을 수 있습니다 . 그런 다음 쿼리를 실행하기 직전에 두 add_filter()줄 을 배치합니다 . 쿼리 후 remove_filter( 'get_meta_sql', 'wpse12814_get_meta_sql' ); remove_filter( 'posts_orderby', 'wpse12814_posts_orderby' );다시 삭제하도록 작성합니다.
Jan Fabry

아-그게 다 말이 되서 너무 일하는거야! 많은 감사 1 월. 그게 도움이 될 것입니다 ...
v3nt

0

라인을 따라 무언가를 시도하십시오 :

$postedtime = get_post_meta($post->ID, 'startDate');

if($postedtime != null){
$orderby = $postedtime;

}else{
$orderby = 'date';
}

알렉스 고맙지 만 이것이 루프에 어떻게 관여하는지 확실하지 않습니까?
v3nt

도! query_posts (array ( 'orderby'=> $ orderby)) 때
Alex Older

0

쿼리 게시 호출은 두 개가 아닌 하나의 쿼리 만 수행합니다. 따라서 두 개의 별도 쿼리를 만든 다음 결과를 연결할 수 없습니다.

여기에서 게시물 세트를 선택한 다음 표시합니다. 해당 세트가 한 번에 선택됩니다. 두 개의 개별 게시물 세트를 가져 와서 병합하려면 get_posts 또는 이와 유사한 작업을 수행해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.