此查询将处理分类法中的两个层次结构。两个以上的层次结构级别,您将需要一个递归的自连接。
这样做的目的是在父级顺序中以正确的子级返回帖子。要创建适当的父级标题,您需要将当前帖子的父分类单元与之前帖子的父分类单元进行比较。在页面顶部打印分类单元标题,并在父分类单元值更改的每个点打印另一个级别。您需要在每个post上调用一个函数来获取父级分类单元,因为我不知道如何将查询中的值传递给post对象。
SELECT *
from wp_posts
LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id)
LEFT JOIN wp_term_taxonomy AS parent ON (wp_term_taxonomy.parent = parent.term_taxonomy_id)
LEFT JOIN wp_terms AS parent_terms ON (parent.term_id = parent_terms.term_id)
WHERE wp_posts.post_type = \'post\'
AND wp_term_taxonomy.taxonomy = \'category\'
and not exists(select 1
from wp_posts AS subposts
LEFT JOIN wp_term_relationships as subtr ON subposts.ID = subtr.object_id
LEFT JOIN wp_term_taxonomy as subtt ON (subtr.term_taxonomy_id = subtt.term_taxonomy_id)
LEFT JOIN wp_terms as subt ON (subtt.term_id = subt.term_id)
LEFT JOIN wp_term_taxonomy AS subparent ON (subtt.parent = subparent.term_taxonomy_id)
where subtt.parent > wp_term_taxonomy.parent
and subposts.ID = wp_posts.ID
AND subtt.taxonomy = wp_term_taxonomy.taxonomy)
ORDER BY IFNULL( parent_terms.slug , wp_terms.slug) ASC, wp_terms.slug ASC;
考虑到这是存档页面的正确SQL,让我们考虑如何使用过滤器实现,例如pre\\u get\\u posts等。
UPDATE上面的SQL查询已经过测试和修改,以返回正确的结果。下面的查询与我最初的查询类似,它为任何有父项的帖子返回两行。
SELECT wp_posts.ID, parent_terms.slug parent_slug, wp_terms.slug, wp_term_taxonomy.taxonomy, wp_term_taxonomy.parent
, IFNULL( parent_terms.slug , wp_terms.slug) sort_col2
from wp_posts
LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id)
LEFT JOIN wp_term_taxonomy AS parent ON (wp_term_taxonomy.parent = parent.term_taxonomy_id)
LEFT JOIN wp_terms AS parent_terms ON (parent.term_id = parent_terms.term_id)
WHERE wp_posts.post_type = \'post\'
AND wp_term_taxonomy.taxonomy = \'category\'
ORDER BY IFNULL( parent_terms.slug , wp_terms.slug) ASC, wp_terms.slug ASC;
请注意这篇文章。id=629在结果中出现两次:
+-----+-------------+---------------+----------+--------+-----------+
| ID | parent_slug | slug | taxonomy | parent | sort_col2 |
+-----+-------------+---------------+----------+--------+-----------+
| 629 | | business | category | 0 | business |
| 629 | business | press-release | category | 3 | business |
| 618 | | media | category | 0 | media |
| 608 | | media | category | 0 | media |
| 624 | | startups | category | 0 | startups |
| 621 | | startups | category | 0 | startups |
+-----+-------------+---------------+----------+--------+-----------+
6 rows in set (0.00 sec)
通过添加
NOT EXISTS(...)
条件:
SELECT wp_posts.ID, parent_terms.slug parent_slug, wp_terms.slug, wp_term_taxonomy.taxonomy, wp_term_taxonomy.parent
, IFNULL( parent_terms.slug , wp_terms.slug) sort_col2
from wp_posts
LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id)
LEFT JOIN wp_term_taxonomy AS parent ON (wp_term_taxonomy.parent = parent.term_taxonomy_id)
LEFT JOIN wp_terms AS parent_terms ON (parent.term_id = parent_terms.term_id)
WHERE wp_posts.post_type = \'post\'
AND wp_term_taxonomy.taxonomy = \'category\'
and not exists(select 1
from wp_posts AS subposts
LEFT JOIN wp_term_relationships as subtr ON subposts.ID = subtr.object_id
LEFT JOIN wp_term_taxonomy as subtt ON (subtr.term_taxonomy_id = subtt.term_taxonomy_id)
LEFT JOIN wp_terms as subt ON (subtt.term_id = subt.term_id)
LEFT JOIN wp_term_taxonomy AS subparent ON (subtt.parent = subparent.term_taxonomy_id)
where subtt.parent > wp_term_taxonomy.parent
and subposts.ID = wp_posts.ID )
ORDER BY IFNULL( parent_terms.slug , wp_terms.slug) ASC, wp_terms.slug ASC;
以及结果,在父级中按子级排序的帖子,并且没有重复记录:
+-----+-------------+---------------+----------+--------+-----------+
| ID | parent_slug | slug | taxonomy | parent | sort_col2 |
+-----+-------------+---------------+----------+--------+-----------+
| 629 | business | press-release | category | 3 | business |
| 618 | | media | category | 0 | media |
| 608 | | media | category | 0 | media |
| 624 | | startups | category | 0 | startups |
| 621 | | startups | category | 0 | startups |
+-----+-------------+---------------+----------+--------+-----------+
5 rows in set (0.00 sec)
<小时>
UPDATE: Function NOT current with the latest SQL above
function wpse69290_query( $pieces, $obj )
{
global $wpdb;
#$pieces[\'fields\'] = "* ";
$pieces[\'join\'] .= " LEFT JOIN `$wpdb->term_relationships` AS trs ON ($wpdb->posts.ID = trs.object_id)";
$pieces[\'join\'] .= " LEFT JOIN `$wpdb->term_taxonomy` AS tt ON (trs.term_taxonomy_id = tt.term_taxonomy_id)";
$pieces[\'join\'] .= " LEFT JOIN `$wpdb->terms` AS t ON (tt.term_id = t.term_id)";
$pieces[\'join\'] .= " LEFT JOIN `$wpdb->term_taxonomy` AS parent ON (parent.parent = trs.term_taxonomy_id)";
$pieces[\'join\'] .= " LEFT JOIN `$wpdb->terms` AS parent_terms ON (parent.term_id = parent_terms.term_id)";
$pieces[\'where\'] .= " AND (tt.taxonomy = \'topics\')";
$pieces[\'orderby\'] = "IFNULL(parent_terms.slug, t.slug) ASC";
$pieces[\'limits\'] = "LIMIT 0, 999";
return $pieces;
}
add_filter( \'posts_clauses\', \'wpse69290_query\', 10, 2 );
是的,不需要使用
prepare()
对于仅具有默认表名的查询部件。