简体   繁体   中英

WooCommerce: Get purchased items for a product category using a SQL query

I am trying to list all of the products bought that belong to a certain product category, for instance all T-shirt orders under the "clothes" product category.

I find the Woocommerce database structure quite confusing and you have to write long queries to get simple information.

Could anyone provide an example query to get all orders by a certain category?

I know this will probably involve wp_woocommerce_order_items and wp_terms tables, but get lost from there.

The following SQL query will give you a list of product IDs purchased at least once that belongs to "clothes" product category slug:

SELECT DISTINCT tr.object_id
FROM wp_term_relationships tr
INNER JOIN wp_term_taxonomy tt
    ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms t
    ON tt.term_id = t.term_id
INNER JOIN wp_woocommerce_order_itemmeta oim
    ON tr.object_id = oim.meta_value
INNER JOIN wp_woocommerce_order_items oi
    ON oim.order_item_id = oi.order_item_id
INNER JOIN wp_posts as o
    ON oi.order_id = o.ID
WHERE tt.taxonomy = 'product_cat'
    AND t.slug = 'clothes'
    AND oim.meta_key = '_product_id'
    AND o.post_type = 'shop_order'
    AND o.post_status IN ('wc-completed','wc-processing')

Tested and works

Or in Wordpress using WPDB class this can be done using:

global $wpdb;

$product_category = 'clothes'; // Term slug

$products_ids = $wpdb->get_col( "
    SELECT DISTINCT tr.object_id
    FROM wp_term_relationships tr
    INNER JOIN wp_term_taxonomy tt
        ON tr.term_taxonomy_id = tt.term_taxonomy_id
    INNER JOIN wp_terms t
        ON tt.term_id = t.term_id
    INNER JOIN wp_woocommerce_order_itemmeta oim
        ON tr.object_id = oim.meta_value
    INNER JOIN wp_woocommerce_order_items oi
        ON oim.order_item_id = oi.order_item_id
    INNER JOIN wp_posts as o
        ON oi.order_id = o.ID
    WHERE tt.taxonomy = 'product_cat'
    AND t.slug = '$product_category'
    AND oim.meta_key = '_product_id'
    AND o.post_type = 'shop_order'
    AND o.post_status IN ('wc-completed','wc-processing')
");

// Pre-formatted raw display (an array of products ids)
echo '<pre>'; print_r($products_ids); echo '</pre>';

NOT SQL but by wp query. Find all your orders and gether orders that have required category. Make new args with post__in attribute.

$m_args_all = array(
    'orderby' => 'date',
    'posts_per_page' => 12,
);

$ordr_cat = 654 // id of required cat
$empty_cat = false;

$orders_all_raw = wc_get_orders( $m_args_all ); //find all orders by your args
if (!empty($orders_all_raw)) { 
    $orders_in_cat = []; 
    foreach ($orders_all_raw as $order_raw) {
        $items = $order_raw->get_items(); //get products of order
        if (!empty($items)) { 
            foreach ($items as $item_id => $item) { //loop for products
                $term_ids = wp_get_post_terms($item->get_product_id(),  'product_cat', array('fields' => 'ids')); // get all id of cats in product
                if (in_array($ordr_cat, $term_ids)) { // if required cat in array of gethered cats add order id to array
                    if (!in_array($order_raw->ID, $orders_in_cat)) {
                        $orders_in_cat[] = $order_raw->ID; //add order with required prod cat to array 
                    }
                }
            }
        }

    }
    if (empty($orders_in_cat)){
        $empty_cat = true;
    }
    else {
        $m_args_all += array('post__in' => $orders_in_cat);
    }

}
if($empty_cat){
    $orders = [];
}
else{
    $orders = wc_get_orders( $m_args_all );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM