I have WooCommerce variable products and a filter which is filtering products based on variation attributes. I have variation attribute depth which has numeric value (from 1 to 20) and the filter is working fine. But I want to display In Stock variations only On the other hand it is displaying all products including out of stock selected depth value (variation). So I want to hide product which will have selected depth value but no stock.

Can I query through Products variation stock ?

Here how it is working right now.

$args = array(
'post_type' => array('product'),
        'meta_query' => array(
                'key' => '_stock_status',
                'value' => 'instock',
                'compare' => '=',

        'tax_query' => array(
                'taxonomy' => 'pa_depth',
                'field' => 'slug',
                'terms' => $wccaf_depth,
                'operator'  => $wccaf_depth ? 'IN' : 'NOT IN'
  • But that $wccaf_depth ? 'IN' : 'NOT IN' is confusing.. – Sally CJ Jun 12 '19 at 4:16
  • As I mention that I have filter on this page and $wccaf_depth is a selected depth value by the user. I have few other option in my filter for example price and these are not required so that is why I added this condition $wccaf_depth ? 'IN' : 'NOT IN'. But I can also tell you that the above code is not working for variation stock and this is what I wanted to know. As it displays products with 0 stock as well which I do not want to. – wplearner Jun 12 '19 at 7:30
  • This 0 stock is of variation level as I am managing stock at variation level and want to query through variations stock. – wplearner Jun 12 '19 at 8:00
  • Ok, please ignore my previous comments and check my answer. And do let me know how it goes.. – Sally CJ Jun 12 '19 at 10:25
  • I am not sure if you have tried this or not but changing your meta query to this should help: 'meta_query' => array( array( 'key' => '_stock', 'value' => '0', 'compare' => '>', ), ), – Faham Shaikh Jun 13 '19 at 14:09

(Note to other readers: The question author and I have already discussed via chat, so I'm going straight to the code.)

I think for performance reason, you should do it this way:

// FIRST PART: Get the variations which are in stock.

$paged = max( 1, get_query_var( 'paged' ) );
$wccaf_depth = array( '19', '1' ); // example
$args = array(
    'post_type'     => 'product_variation',
    'meta_query'    => array(
        'relation' => 'AND',
            'key'     => '_stock_status',
            'value'   => 'instock',
            'compare' => '=',
            'key'     => 'attribute_pa_tread-depth',
            'value'   => $wccaf_depth,
            'compare' => 'IN',
    'fields'         => 'id=>parent',
    'paged'          => $paged,
    'posts_per_page' => 1, // example
    'groupby'        => 'post_parent', // *this is a custom query arg

$q = new WP_Query( $args );
$parent_ids = wp_list_pluck( $q->posts, 'post_parent' );

// SECOND PART: Get the parent products. Here you don't need the above
// meta_query, but you can of course make other meta queries.

$args = array(
    'post_type' => 'product',
    'post__in'  => $parent_ids,

$loop = new WP_Query( $args );
// Run your loop here.

// Paginate the first part.
echo paginate_links( array(
    'total'   => $q->max_num_pages,
    'current' => $paged,
) );

And be sure to add this filter to your functions file:

add_filter( 'posts_groupby', 'custom_posts_groupby', 10, 2 );
function custom_posts_groupby( $groupby, $query ) {
    if ( 'post_parent' === $query->get( 'groupby' ) ) {
        global $wpdb;
        return "$wpdb->posts.post_parent";
    return $groupby;

However, if this approach (where we paginate the first part) doesn't work for you, let me know. But you can actually always view the answer's revisions..

| improve this answer | |
  • For the WP_Query you have mention post type 'product_variation' but I need to use post type 'product'. I have 10 thousands products and I have some filter in sidebar. I am filtering products through price, depth variation and few custom fields. All these products are variable but I am displaying products with their variations on shop page. This is completely a custom page. Let me know if you need any information and thank you so much for your time and help. – wplearner Jun 12 '19 at 13:32
  • Can you re-explain what you need? Perhaps I misunderstood your question.. and despite the code may not (completely) help you, have you tried it? – Sally CJ Jun 12 '19 at 15:20
  • Yes I tried this already before posting here but it was not working. I have a shop page where I am displaying all my products and I have filters on this page. We have price, depth and few custom product meta fields in my filter. On selection of depth value it is displaying filtered results correctly but the problem is that it is displaying products even with a 0 stock for that selected depth value. I want to display products which will have something in stock for that selected depth from a filter. So I want to filter through variations stock in my main WordPress query. – wplearner Jun 12 '19 at 17:12
  • I actually meant the code in my answer. But anyway, can you post the current code you use which works for filtering the products by the depth value? – Sally CJ Jun 12 '19 at 17:30
  • 1
    This code is working perfectly. Thank you for your help and for valuable time. – wplearner Jun 14 '19 at 15:34

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