I've created a custom query to pull all posts from a custom post type, ordered by comment count. It's your run-of-the-mills custom query:


 $querystr = "
    SELECT wposts.* 
    FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
    WHERE wposts.ID = wpostmeta.post_id 
    AND wposts.post_status = 'publish' 
    AND wposts.post_type = 'Tutorials' 
    ORDER BY wposts.comment_count DESC
 $tutorialposts = $wpdb->get_results($querystr, OBJECT);


 <?php if ($tutorialposts): ?>
 <?php global $post; ?>
 <?php $i = 0; ?> 
 <?php foreach ($tutorialposts as $post): ?>
 <?php $i++; ?>
 <?php setup_postdata($post); ?>
<h2><?php echo $i ?>:&nbsp;<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"> <?php the_title(); ?></a></h2>
 <?php endforeach; ?>
 <?php endif; ?>

It has a little code added to it to number the posts. But I took this code out and the same problem persisted.

It actually does what it's supposed to do! In fact, it's so excited about doing what it's supposed to do, that it does it twice.

Screen shot of issue

Also if anyone could tell me how to parse this code so it only shows the top 10 posts retrieved by the query that would be excellent. But I could probably figure that out on my own, that's just me being kind of lazy.

I really just need to know why it's pulling each post and displaying it twice o.0


There is really no reason to use raw sql to query posts. You can accomplish just about any type of query using the WordPress API. For full reference see the codex, Function Reference query posts. Try the following:

global $post;

    'post_type' => 'tutorial',
    'orderby' => 'comment_count',
    'posts_per_page' => 10

   $posts= query_posts($args);

foreach ($posts as $post) :

//do stuff

  • I tried that first, actually. I'm using the foreach because that seems to be the only way to get my ordered list to work. And when I use the above query with a foreach, it actually displays everything except custom post types. It's like I never even set that value. – Lynne Feb 28 '11 at 4:13
  • 1
    You can still do a foreach loop with query_posts. See edited answer. – Chris_O Feb 28 '11 at 4:44
  • No have_posts/the_post then? :( A puppy just died... – t31os Feb 28 '11 at 14:04
  • 1
    I'd rather sacrifice a puppy than letting a bunch of kittens get killed the way she was doing it before. – Chris_O Feb 28 '11 at 14:26
  • Well sure, but i thought it might be nice to encourage the use of the WP_Query convenience methods(have_posts, etc) and template tags, that said your comment gave me a giggle, so i +1'ed.. :) – t31os Mar 3 '11 at 12:48

Why are you joining with postmeta if you don't use it neither in WHERE nor get a field from it?

Your double result is because you're running a non-distinct query and since you're joining postmeta, MySQL delivers a separate record for each postmeta record, even though you're only retrieving the fields from posts.

So either drop the postmeta join or do SELECT DISTINCT, the former would be better.

And i agree with Chris_O...always better to use query vars if you can, as WP then makes sure you don't cause yourself this kind of trouble.


I had to define some post meta field (custom field, taxonomy, or tag) and add it to the query select:

AND wpostmeta.meta_key = 'Platform'

Now it only shows each post once, but I am now locked in to defining a value to the custom field "platform" for every post under "Tutorials."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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