Deleting WordPress records based on Nested Selects

Last week I was helping with a task for deleting terms from the WordPress database based on an array of IDs from a select statement.

Since I have a thing for database systems (spent a few years playing in various mid-size and large projects with Oracle and PostgreSQL databases before migrating to MySQL) I thought it was a 20sec job to build the query having the select ready and delete the data. However, I got stuck in the process and took me about 15min to actually form the proper statement.

The final code looks like that (with a bit different where clause for the nested select):

[sql]

DELETE FROM
wp_terms
WHERE term_id IN
( SELECT * FROM (
SELECT wp_terms.term_id
FROM wp_terms
JOIN wp_term_taxonomy
ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE taxonomy = ‘product_tag’
AND count = 0
) as T
);

[/sql]

Normally what a nested select is used for is to fetch some entries to be used in a where clause in the main query, avoiding the limitations of the ANSI SQL to not have variables. Alternatively, one could either build stored procedures (to take advantage of variables, loops (cursors) and conditionals) or create temporary tables to fetch the data – both not being optimal for a single transaction.

Where MySQL differs from the regular RDBMS is the inability to fetch and update data in a table at the same time. My initial form was in the following order: “delete from X where term_id in ( select term_id from X where … )” but applying both retrieval and removal operations on the same table is prohibited by the MySQL team.

What works here is using a buffer table and assigning an alias to the table. So, for building the query, you need to follow these steps:

  1. write your SELECT statement to properly fetch the array of IDs to be deleted later
  2. write your DELETE statement as you would have written it if you had the static array of IDs
  3. wrap you SELECT statement in a “SELECT * FROM (initial select here) as T

Using the buffer table and adding the alias to it are the crucial step for MySQL to handle both delete and select within the same table.


My name is Mario Peshev, a global SME Business Advisor running digital businesses for 20 the past years.

Born in Bulgaria, Europe, I gained diverse management experience through my training work across Europe, North America, and the Arab world. With 10,000+ hours in consulting and training for organizations like SAP, VMware, CERN, I’ve dedicated a huge amount of my time to helping hundreds of SMEs growing in different stages of the business lifecycle.

My martech agency DevriX grew past 50 people and ranks as a top 10 WordPress global agency and Growth Blueprint, my advisory firm, has served 400+ SME founders and executives with monthly ongoing strategy sessions.


Follow me at:

Latest Editions:

Browse by Category

Latest Answers: