I want to get all categories of some selected posts.
For example, I have post IDs like 1,2,3. Post 1,2,3 has categories {cat, dog}, {dog, mouse}, {mouse} respectively. I want a category list which includes {cat, dog, mouse}.

I have looked into two WP functions,
get_terms: does not allow me to supply post ids
wp_get_post_terms: this only returns terms for a single post

I have found two ways to achieve the same:

1. Loop
Get the post ids first then use a loop to get categories for each post. That is too many queries when there are too many posts.

2. Custom query
the following query also gives me desired result. but it's not really a WP's style to run a custom query. I really want to avoid this solution.

select * from sh_7_terms
where term_id in (
    select distinct(sh_7_terms.term_id)
    from sh_7_terms, sh_7_term_taxonomy, sh_7_term_relationships, sh_7_posts
        sh_7_terms.term_id = sh_7_term_taxonomy.term_id AND
        sh_7_term_taxonomy.term_taxonomy_id = sh_7_term_relationships.term_taxonomy_id AND
        sh_7_term_relationships.object_id = sh_7_posts.ID AND
        sh_7_term_taxonomy.taxonomy = 'product_cat' and 
        sh_7_posts.ID IN ( 1, 2, 3 )

Is there any other optimized solution out there?

  • Well, what do you need returned? If it's just IDs - multiple queries won't matter because they'll be fast. If you need all things or Objects then creating a function that queries is your next best bet. AFAIK WP doesn't have a quick or efficient way to get all assigned categories from multiple posts.
    – Howdy_McGee
    Oct 17, 2016 at 14:59
  • I think you are right, looks like multiple quires is the only option I got. But still wanted to hear some other opinions.
    – Arif
    Oct 17, 2016 at 15:07
  • I'd be happier if someone who better understood the process confirmed or explained with more specifics and higher confidence, but, if I understand correctly, since wp_get_post_terms() relies on the $wpdb class, I believe that the result is cached - not just the given array, but the entire column - meaning that you wouldn't be performing a unique new query every time you got the terms for a different post. Assembling the unique category names would be straightforward PHP after that. Or have I misunderstood your actual concern?
    – CK MacLeod
    Oct 18, 2016 at 6:29

1 Answer 1


Enter wp_get_object_terms - it accepts an array of object IDs and retrieves all of their (unique) attached terms:

$terms = wp_get_object_terms( [ 1, 2, 3 ], 'category' );
foreach ( $terms as $term )
    echo "$term->name<br />";
  • $post_ids = array( 1,2,3 ) ; $cat_names = wp_get_object_terms( $post_ids, 'category', array( 'fields' => 'names' ) ) ;
    – CK MacLeod
    Oct 18, 2016 at 15:26
  • Thanks TheDeadMedic. That's the function I was looking for. Cheers :)
    – Arif
    Oct 19, 2016 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.