เรียงตามมูลค่าเมตาหรือวันที่?


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 เริ่มต้นที่เผยแพร่แม้ว่าอาจจะผิดหรือเปล่า? วิธีใด
ก็ตามที่

ตกลงดังนั้นมันจึงไม่ใช่เขตข้อมูลเมตาในตารางโพสต์
Bainternet

แก้ไขข้อโต้แย้งการสืบค้นของคุณหวังว่าจะไม่บิดเบือนสิ่งที่คุณกำลังอธิบายอยู่โปรดอย่าลังเลที่จะยกเลิกหากจำเป็น
t31os

ไชโย t31os - แก้ไขอีกครั้งเพื่อให้ชัดเจนขึ้น ต้องใช้เพื่อเลือกเนื้อหาที่เก่ากว่าตอนนี้โดยใช้ startDate และหากยังไม่ได้ตั้ง 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;
}

ส่วนคำสั่งถูกกรองผ่าน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-> คำนำหน้า} แทน ...
goldenapples

@goldenapples: ใช่คุณสามารถพูดคุยทั่วไปได้ แต่มันก็มีความเฉพาะเจาะจงมากสำหรับการสืบค้นนี้ (มันจะทำให้การสืบค้นอื่น ๆ มีส่วนเมตา) ซึ่งฉันคิดว่ามันไม่จำเป็น
Jan Fabry

ขอบคุณแจน - นั่นคือเครื่องเปิดตา! ยังคงได้รับการจับด้วย wordpress และสงสัยว่าสิ่งนี้เรียกว่าในหน้าของฉัน และฉันจะ 'ปลดเบ็ด' ได้อย่างไร เช่น // $ theQuery ... จากนั้น <? php if (have_posts ()): ในขณะที่ (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

อ่า - มันก็สมเหตุสมผลแล้วและก็ใช้ได้เช่นกัน! ขอบคุณมาก Jan. Thats จะเป็นประโยชน์ ...
v3nt

0

ลองทำตามสิ่งต่อไปนี้:

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

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

}else{
$orderby = 'date';
}

ขอบคุณ alex แต่ไม่แน่ใจว่าสิ่งนี้เกี่ยวข้องกับการวนรอบหรือไม่
v3nt

DOH! เมื่อคุณ query_posts (อาร์เรย์ ('orderby' => $ orderby))
Alex เก่ากว่า

0

การเรียกโพสต์แบบสอบถามจะสร้างแบบสอบถามเพียงหนึ่งแบบสอบถามไม่ใช่สองรายการ ดังนั้นไม่คุณไม่สามารถสร้างแบบสอบถามที่แยกกันสองรายการแล้วต่อผลลัพธ์ที่ได้

จำไว้ว่าคุณกำลังเลือกชุดโพสต์ที่นี่จากนั้นแสดง ชุดนั้นถูกเลือกทั้งหมดในครั้งเดียว หากคุณต้องการโพสต์แยกกันสองชุดจากนั้นรวมเข้าด้วยกันนั่นคือสิ่งที่คุณจะต้องทำด้วย get_posts หรือคล้ายคลึงกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.