I'm working on creating some SQL Views for my Wordpress database to more easily view online orders generated via the WooCommerce plugin. I'm familiar with the WooCommerce structure and where the data is stored but being an SQL novice I'm getting stuck at the last hurdle.
I've been able to create the first view of all the order details using this reference:
http://codecharismatic.com/sql-script-to-get-all-woocommerce-orders-including-metadata/
Now I need to create a similar view of the line items for each of these orders. There are 2 tables that store order item details:
wp_woocommerce_order_items wp_woocommerce_order_itemmeta
I've been able to create the basic list of records from the wp_woocommerce_order_items table as follows:
SELECT order_item_id,order_item_name,order_item_type,order_id
FROM ocm_woocommerce_order_items
ORDER BY order_id
This returns a nice list of records like this:
order_item_id order_item_name order_item_type order_id
2 Widgets line_item 9
3 Widgets line_item 10
4 Widgets line_item 11
5 Woo Logo line_item 473
6 Woo Logo line_item 473
I would now like to add additional columns for each line item from the wp_woocommerce_order_itemmeta table. This table contains multiple records for each line item like this:
meta_id order_item_id meta_key meta_value
136 16 _qty 4
137 16 _tax_class
138 16 _product_id 87
139 16 _variation_id 0
140 16 _line_subtotal 36
141 16 _line_total 36
142 16 _line_subtotal_tax 3.6
143 16 _line_tax 3.6
I would like to convert each of these into a new column so my output would consist of:
order_item_id, order_item_name, order_item_type, order_id, qty, tax_class, product_id, variation_id, line_subtotal, line_total, line_subtotal_tax, line_tax
I'm not sure which SQL syntax to use here - I've tried to use a similar syntax to the link above but haven't been able to get it to work so far and not sure if that is indeed the correct syntax.
Orders are a Custom Post Type (CPT), so they are stored in the wp_posts table. If you search the post_type field for 'shop_order', SQL will retrieve all orders. Then, you must search the wp_postmeta table for all the records with post_id matching the id of the order post.
All data associated with a WooCommerce order is stored in the WordPress database. This includes order data, product data, customer data, and any other data related to the order. The database table that stores this information is called the “posts” table.
I managed to work this out by trial and error. Here's the query that worked in the end:
select
p.order_id,
p.order_item_id,
p.order_item_name,
p.order_item_type,
max( CASE WHEN pm.meta_key = '_product_id' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as productID,
max( CASE WHEN pm.meta_key = '_qty' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as Qty,
max( CASE WHEN pm.meta_key = '_variation_id' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as variationID,
max( CASE WHEN pm.meta_key = '_line_total' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as lineTotal,
max( CASE WHEN pm.meta_key = '_line_subtotal_tax' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as subTotalTax,
max( CASE WHEN pm.meta_key = '_line_tax' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as Tax,
max( CASE WHEN pm.meta_key = '_tax_class' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as taxClass,
max( CASE WHEN pm.meta_key = '_line_subtotal' and p.order_item_id = pm.order_item_id THEN pm.meta_value END ) as subtotal
from
ocm_woocommerce_order_items as p,
ocm_woocommerce_order_itemmeta as pm
where order_item_type = 'line_item' and
p.order_item_id = pm.order_item_id
group by
p.order_item_id
You can use this query to get all completed orders including all metadata.
SELECT
p.ID as order_id,
p.post_date,
max( CASE WHEN pm.meta_key = '_billing_email' and p.ID = pm.post_id THEN pm.meta_value END ) as billing_email,
max( CASE WHEN pm.meta_key = '_billing_first_name' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_first_name,
max( CASE WHEN pm.meta_key = '_billing_last_name' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_last_name,
max( CASE WHEN pm.meta_key = '_billing_address_1' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_address_1,
max( CASE WHEN pm.meta_key = '_billing_address_2' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_address_2,
max( CASE WHEN pm.meta_key = '_billing_city' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_city,
max( CASE WHEN pm.meta_key = '_billing_state' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_state,
max( CASE WHEN pm.meta_key = '_billing_postcode' and p.ID = pm.post_id THEN pm.meta_value END ) as _billing_postcode,
max( CASE WHEN pm.meta_key = '_shipping_first_name' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_first_name,
max( CASE WHEN pm.meta_key = '_shipping_last_name' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_last_name,
max( CASE WHEN pm.meta_key = '_shipping_address_1' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_address_1,
max( CASE WHEN pm.meta_key = '_shipping_address_2' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_address_2,
max( CASE WHEN pm.meta_key = '_shipping_city' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_city,
max( CASE WHEN pm.meta_key = '_shipping_state' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_state,
max( CASE WHEN pm.meta_key = '_shipping_postcode' and p.ID = pm.post_id THEN pm.meta_value END ) as _shipping_postcode,
max( CASE WHEN pm.meta_key = '_order_total' and p.ID = pm.post_id THEN pm.meta_value END ) as order_total,
max( CASE WHEN pm.meta_key = '_order_tax' and p.ID = pm.post_id THEN pm.meta_value END ) as order_tax,
max( CASE WHEN pm.meta_key = '_paid_date' and p.ID = pm.post_id THEN pm.meta_value END ) as paid_date,
( select group_concat( order_item_name separator '|' ) from wp_woocommerce_order_items where order_id = p.ID ) as order_items
FROM
wp_posts p
join wp_postmeta pm on p.ID = pm.post_id
join wp_woocommerce_order_items oi on p.ID = oi.order_id
WHERE
post_type = 'shop_order' and
post_date BETWEEN '2021-07-01' AND '2021-08-01' and
post_status = 'wc-completed'
group by
p.ID
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With