問題描述
我想得到所有沒有附件的帖子的列表,並刪除它們。
This question 需要獲取所有附件的帖子,但我想要反過來。
強力的方法是獲取所有帖子,然後單獨迴圈,然後檢查他們是否具有附件。但是如果可能,我想避免它。
最佳解決思路
我很好奇查詢所有沒有任何附件的帖子的 SQL 方式。
方法#1 – 使用 NOT IN 的子查詢
這是我第一次嘗試構建這樣一個查詢:
global $wpdb;
$sql = "
SELECT p1.ID, p1.post_title
FROM {$wpdb->posts} p1
WHERE p1.post_type = 'post'
AND p1.post_status = 'publish'
AND p1.ID NOT IN (
SELECT DISTINCT p2.post_parent
FROM {$wpdb->posts} p2
WHERE p2.post_type = 'attachment' AND p2.post_parent > 0
)
ORDER BY p1.post_date DESC
";
// Fetch posts without attachments:
$posts_without_attachments = $wpdb->get_results( $sql );
// Display posts without attachments:
foreach( $posts_without_attachments as $post )
{
echo $post->post_title . '<br/>';
}
這恰好與 @ toscho 的查詢非常相似,但在語法中更加簡化;-)
方法#2 – LEFT JOIN 與 IS NULL
這個查詢似乎也可以工作:
global $wpdb;
$sql = "
SELECT p1.ID, p1.post_title
FROM {$wpdb->posts} p1
LEFT JOIN {$wpdb->posts} p2
ON ( p2.post_parent = p1.ID AND p2.post_type = 'attachment' )
WHERE p1.post_type = 'post'
AND p1.post_status = 'publish'
AND p2.post_parent IS NULL
ORDER BY p1.post_date DESC
";
// Fetch posts without attachments:
$posts_without_attachments = $wpdb->get_results( $sql );
在那裡我們自己加入帖子表,然後在附件的父列中選擇 NULL 行。
方法#3 – WP_Query 與 posts_where 過濾器又名方法#1
我們也可以使用 posts_where 過濾器修改 WP_Query():
// Filter all posts without attachments:
add_filter( 'posts_where', 'wpse_no_attachments' );
// Query:
$q = new WP_Query( array( 'post_type' => 'post', 'posts_per_page' => -1 ) );
// Remove the filter:
remove_filter( 'posts_where', 'wpse_no_attachments' );
哪裡:
function wpse_no_attachments( $where )
{
global $wpdb;
$where .= " AND {$wpdb->posts}.ID NOT IN (
SELECT DISTINCT wpse.post_parent
FROM {$wpdb->posts} wpse
WHERE wpse.post_type = 'attachment' AND wpse.post_parent > 0 ) ";
return $where;
}
次佳解決思路
如果您對連結答案完全相反,您只需使用此查詢即可獲取具有附件的所有帖子,然後將其 ID 作為 WP_Query 的 post__not_in 引數:
$attachment_args = array(
'post_type' => 'attachment',
'post_mime_type' => 'image',
'post_status' => 'inherit',
'posts_per_page' => -1,
'post_parent__not_in' => array(0),
'meta_query' => array(
array(
'key' => '_thumbnail_id',
'value' => 'x',
'compare' => 'NOT EXISTS'
)
),
'fields' => 'post_parent'
);
$atts = new WP_Query($args);
$parents = array_unique(wp_list_pluck($atts->posts,'post_parent'));
$post_args = array(
'post_type' => 'post',
'posts_per_page' => -1
'post__not_in' => $parent
'post_status' => 'any'
);
// Posts with no attachment:
$post_query = new WP_Query( $post_args );
更新 Toscho 指出我做這個一個查詢。而且,當然這可以用一個簡單的 SQL Query 來處理:
<?php
$query = <<<SQL
SELECT p.`ID` FROM {$wpdb->posts} p
WHERE p.`post_type` = 'post'
AND p.`post_status` = 'publish'
AND p.`ID` NOT IN (
SELECT DISTINCT a.`post_parent` FROM {$wpdb->posts} a
WHERE a.`post_type` = 'attachment'
AND a.`post_parent` != 0
)
SQL;
//posts with no attachment
$results = $GLOBALS[ 'wpdb' ]->get_results( $query );
請注意,這與從參考答案中獲取的變體略有不同,因為該查詢在影像和 post-thumbnail 之間沒有區別,並且還查詢任何型別的附件。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。