I found this post: How WooCommerce Coupons are stored in Database?
It is working correct and loads everything of the coupons in the database.
Instead of a SELECT query I want to DELETE all of this.
How do I need to modify the code?
SELECT p.`ID`,
p.`post_title` AS coupon_code,
p.`post_excerpt` AS coupon_description,
Max(CASE WHEN pm.meta_key = 'discount_type' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS discount_type, -- Discount type
Max(CASE WHEN pm.meta_key = 'coupon_amount' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS coupon_amount, -- Coupon amount
Max(CASE WHEN pm.meta_key = 'free_shipping' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS free_shipping, -- Allow free shipping
Max(CASE WHEN pm.meta_key = 'expiry_date' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS expiry_date, -- Coupon expiry date
Max(CASE WHEN pm.meta_key = 'minimum_amount' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS minimum_amount, -- Minimum spend
Max(CASE WHEN pm.meta_key = 'maximum_amount' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS maximum_amount, -- Maximum spend
Max(CASE WHEN pm.meta_key = 'individual_use' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS individual_use, -- Individual use only
Max(CASE WHEN pm.meta_key = 'exclude_sale_items' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS exclude_sale_items, -- Exclude sale items
Max(CASE WHEN pm.meta_key = 'product_ids' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS product_ids, -- Products
Max(CASE WHEN pm.meta_key = 'exclude_product_ids'AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS exclude_product_ids, -- Exclude products
Max(CASE WHEN pm.meta_key = 'product_categories' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS product_categories, -- Product categories
Max(CASE WHEN pm.meta_key = 'exclude_product_categories' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS exclude_product_categories,-- Exclude Product categories
Max(CASE WHEN pm.meta_key = 'customer_email' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS customer_email, -- Email restrictions
Max(CASE WHEN pm.meta_key = 'usage_limit' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS usage_limit, -- Usage limit per coupon
Max(CASE WHEN pm.meta_key = 'usage_limit_per_user' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS usage_limit_per_user, -- Usage limit per user
Max(CASE WHEN pm.meta_key = 'usage_count' AND p.`ID` = pm.`post_id` THEN pm.`meta_value` END) AS total_usaged -- Usage count
FROM `wp_posts` AS p
INNER JOIN `wp_postmeta` AS pm ON p.`ID` = pm.`post_id`
WHERE p.`post_type` = 'shop_coupon'
AND p.`post_status` = 'publish'
GROUP BY p.`ID`
ORDER BY p.`ID` ASC;
FIXED to delete coupons from database with it’s postmeta by running 2 queries:
DELETE FROM `wp_posts` WHERE `post_type` = 'shop_coupon';
DELETE FROM
`wp_postmeta`
WHERE
(
meta_key = 'discount_type'
OR meta_key = 'coupon_amount'
OR meta_key = 'individual_use'
OR meta_key = 'product_ids'
OR meta_key = 'exclude_product_ids'
OR meta_key = 'usage_limit'
OR meta_key = 'limit_usage_to_x_items'
OR meta_key = 'expiry_date'
OR meta_key = 'free_shipping'
OR meta_key = 'exclude_sale_items'
OR meta_key = 'product_categories'
OR meta_key = 'exclude_product_categories'
OR meta_key = 'minimum_amount'
OR meta_key = 'maximum_amount'
OR meta_key = 'customer_email'
OR meta_key = 'usage_limit_per_user'
);
3
Answers
If the select statement above returns all the rows you would like to delete, then you just need to replace the select with delete and remove the order by as it isn’t needed. Like so:
Assuming you want to delete from
wp_posts
, you just need to get the list ofIDs
to delete:You’re not referencing any of the columns in your
SELECT
list, so you don’t need to include them in your sub-query. You can also remove theGROUP BY
since you just want a list of theIDs
.You can probably re-write the
DELETE
a little cleaner usingEXISTS
or a join instead ofIN
, but either way will give you the same result.There are a number of problems with most solutions:
meta_key
is dangerous: some posts other than coupons may for example own'product_ids'
meta data.wp_
.Still, in many cases running such a query does make sense. A query which deletes the coupons and exactly determines all their associated meta data does use a join based on
wp_posts.ID
:A somewhat less intrusive and dangerous way to do it, is to move everything into trash:
… and empty the trash from within the WordPress backend. This gives plugins a chance to invoke filters and hooks and is a great solution for many
post_type
s. I would suggest to use that for more complex types should as orders with associated items, comments and more. Both queries can be limited to only affect published posts: