Skip to content

Instantly share code, notes, and snippets.

@mikaelz
Created January 27, 2016 11:37
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save mikaelz/9f98dcf9664c51e88900 to your computer and use it in GitHub Desktop.
Save mikaelz/9f98dcf9664c51e88900 to your computer and use it in GitHub Desktop.
Remove all WooCommerce product categories and tags
<?php
require dirname(__FILE__).'/wp-blog-header.php';
$wpdb->query("DELETE a,c FROM wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
WHERE c.taxonomy = 'product_tag'");
$wpdb->query("DELETE a,c FROM wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
WHERE c.taxonomy = 'product_cat'");
DELETE a,c FROM wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
WHERE c.taxonomy = 'product_tag';
DELETE a,c FROM wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
WHERE c.taxonomy = 'product_cat'
@jfrez
Copy link

jfrez commented Feb 26, 2016

this is great! thanks!

@miweb777
Copy link

Nice one. Just had to adjust my table name from "wp_terms" to my database table name "wpdn_terms" and so forth.
Worked perfectly. Thankyou so much.

@ilyachase
Copy link

Seems to be it's not deleting products since they are stored in wp_posts with post_type = product.

@mumaromania
Copy link

mumaromania commented Jun 25, 2018

Hi, i have a woocommerce website,
my database name is: limiykm_wp1
When i paste the code and change db name, like this below, it gives me the message:
Sorry, but your code causes a "Fatal error", so it is not applied!
Please, check the code and try again.

The code i did paste is this, as above only changed the db name:

query("DELETE a,c FROM limiykm_wp1 AS a LEFT JOIN limiykm_wp1_taxonomy AS c ON a.term_id = c.term_id LEFT JOIN limiykm_wp1_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id WHERE c.taxonomy = 'product_tag'"); $wpdb->query("DELETE a,c FROM limiykm_wp1 AS a LEFT JOIN limiykm_wp1_taxonomy AS c ON a.term_id = c.term_id LEFT JOIN limiykm_wp1_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id WHERE c.taxonomy = 'product_cat'"); Please help, i am no programmer, just a regular user.

@BrookeDot
Copy link

Just an FYI there's a missing ; at the end of the second DELETE statement in remove-all-product-categories-tags.sql Cheers!

@hellerbenjamin
Copy link

Thanks. Saved me some time looking up the structure!

@JakeQZ
Copy link

JakeQZ commented Jul 15, 2020

There are a couple of issues with this where it could be improved:

  • It does not remove entries from the termmeta table, which will end up orphaned (and can build up to the millions on even a small project);
  • It removes the default WooCommerce category (ID = default_product_cat option).

I have nonetheless found it useful on a 'dev' box, particularly when working with 'product import'. Thanks :)

@gnanet
Copy link

gnanet commented Aug 26, 2023

A bit nicer variant, that includes the table_prefix dynamically:

<?php
error_reporting(E_ALL & ~E_NOTICE);

$logname = basename(__FILE__, ".php").'.log';
$logfullpath = __DIR__.'/'.$logname;

function do_log($logstring) {
    global $logfullpath;
    if ( empty($logstring) === true ) { return; }
    date_default_timezone_set('Europe/Berlin'); // Set your local timezone
    error_log(date('Y.m.d H:i:s')." ".(string) $logstring, 3,$logfullpath);
}

// Specify below the full path to the root of the wp installation, without leading slash
$wpbasedir="ABSOLUTE_PATH_TO_WP_DOCUMENTROOT";

if ( file_exists($wpbasedir."/wp-load.php") )
{
    define('WP_USE_THEMES', false);
    require($wpbasedir.'/wp-load.php');
    global $wpdb;
    $wpdb_query_res = $wpdb->query("DELETE a,c FROM {$wpdb->prefix}terms AS a 
                  LEFT JOIN {$wpdb->prefix}term_taxonomy AS c ON a.term_id = c.term_id
                  LEFT JOIN {$wpdb->prefix}term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
                  WHERE c.taxonomy = 'product_tag'");
    do_log("product tags deleted");
    $wpdb_query_res = $wpdb->query("DELETE a,c FROM {$wpdb->prefix}terms AS a
                  LEFT JOIN {$wpdb->prefix}term_taxonomy AS c ON a.term_id = c.term_id
                  LEFT JOIN {$wpdb->prefix}term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
                  WHERE c.taxonomy = 'product_cat'");
    do_log("product categories deleted");
} else {
    echo "Could not load wp core\n";
}

@JakeQZ
Copy link

JakeQZ commented Aug 26, 2023

Would be nice to have some commentary on what the SQL queries are doing. I am getting old and spent 20 years away from databases ;)

@gnanet
Copy link

gnanet commented Aug 26, 2023

To understand them, you go from bottom first, and then top2down:

  • the first query filters for product_tag as taxonomy type, and deletes all terms, the connected taxonomies, and their relation-data
  • the second query filters for product_cat as taxonomy type, and deletes all terms, the connected taxonomies, and their relation-data

To be honest, as i understand the docs, both queries specifiy to delete rows in terms and term_taxonomies only by writing a,c

@JakeQZ
Copy link

JakeQZ commented Aug 26, 2023

To be honest, as i understand the docs

The docs on the database are few and far between, IIRC.

The solution here leaves orphans in other tables, so is not complete. The orhpans should be perhaps have been linked via a foreign key by the original programmers to prevent such issues, but we are where we are.

@gnanet
Copy link

gnanet commented Aug 26, 2023

To be honest, as i understand the docs

The docs on the database are few and far between, IIRC.

The solution here leaves orphans in other tables, so is not complete. The orhpans should be perhaps have been linked via a foreign key by the original programmers to prevent such issues, but we are where we are.

I am actually woking on a project, where i need a good bunch of cleanup sql-queries, to get rid of all product, attribute category etc and also orders and customers. but the article below seems outdated:
https://www.businessbloomer.com/woocommerce-database-explained-how-it-works-and-where-to-find-data/

simply by looking i found **wc_product_attributes_lookup ** also worth for cleaning :(

if i finish the cleanup, ill try to summarize it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment