问题描述
我想得到所有没有附件的帖子的列表,并删除它们。
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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。