Delete wp users based on role and registration date - mysql

I have about 180000 users in my wp_users database. Most of them are old and dormant. I fear this is slowing down my site (is this likely?). I want to safely delete old accounts along with all their associated data.
Using bulk delete plugins does not work as they timeout with so many users. I want to do it with mysql instead. By searching around I have found the following code:
DELETE
wp_users,
wp_usermeta
FROM
wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE
meta_key = 'wp_capabilities' AND
meta_value LIKE '%subscriber%' AND
user_registered < NOW() - INTERVAL 360 DAY
The code works but is it safe and is it the best way? Will it delete their associated meta data etc.

Please first take a backup of your database before running this query
Yes You can use this query to delete the user & user_meta data but if your theme/plugin saving users data in some others table(if you are using any plugin that store user data in other table) than you have to look again in database and modify your query according to this..

Related

SQL query to delete WP users with duplicate first and last names

We have a woocommerce site that has had a backdoor registration for years resulting in thousands of spam accounts.
I've been able to remove all of the ".ru" and other spam email accounts but there are many gmail addresses being used.
The one thing that seems to be common for many of these is that the first and last name are identical ex: "Donaldpat Donaldpat".
How would I write an SQL query that would delete the users from the wp_users table that have an identical value for first and last name in the related wp_usermeta table values?
would it be something like this:
DELETE FROM wp_users
WHERE EXISTS (
SELECT * FROM wp_usermeta
WHERE wp_usermeta.user_id = wp_users.ID
AND wp_usermeta.first_name = wp_usermeta.last_name
)
You can try this, what I'm doing here is separating the users.ID that I don't need so I just have the tables that I want to remove. Instead of using EXISTS I decided to use IN because that way you get the list ID directly, and remove them.
DELETE FROM wp_users
WHERE wp_users.ID IN (
SELECT DISTINCT user_id
FROM wp_usermeta
WHERE wp_usermeta.first_name = wp_usermeta.last_name
)
I hope this was helpful.

SQL query to get recently created users in OIM

Is there a SQL query for users created in OIM. There are no dates provided while creating users in OIM, But we need to find the users on the basis of their creation date.
Select * from usr where to_date(usr_create)>to_date('01-Jun-2016', 'DD-MON-YYYY');

SQL Query for WordPress/WooCommerce in PHPmyAdmin to select spam users

I have a WordPress database that has approximatly 28000 spam user`registrations in there which I some how need to isolate and delete without removing any actual customers.
I have noticed that all of the spam user registrations have an empty meta_value for a specific meta_key
The meta_key in question is billing_first_name
Therefore, I am trying to write a query I can execute in PHPmyAdmin that will return a list of all user IDs that have an empty meta_value for the meta_key billing_first_name so that I can then delete all of these users from the _usermeta table AND the _users table.
I found a user online who had a similar issue: https://wordpress.org/support/topic/deleting-spam-user-accounts-from-site-with-woocommerce
He wrote the following query that I have attempted to run on my database:
SELECT * FROM wp_usermeta JOIN wp_users ON (wp_usermeta.user_id = wp_users.ID) WHERE user_id NOT IN (SELECT um1.user_id FROM wp_usermeta um1 WHERE um1.meta_key = 'shipping_first_name')
However, its only returning 137 results, and with 28000+ plus registration, but only around 1000 actual orders, I have a heck of a lot more than 137 spam accounts in the database.
I have tried adapting the query to expand upon it and get it to do what I want, but I am not really a "database" person and am not having much luck.
My attempt was:
SELECT * FROM wv5_usermeta JOIN wv5_users ON (wv5_usermeta.user_id = wv5_users.ID) WHERE user_id NOT IN (SELECT um1.user_id FROM wv5_usermeta um1 WHERE um1.meta_key = 'billing_first_name' AND um1.meta_value IS NOT NULL)
Can someone help me formulate a working query that I can use?
Note that my attempt was based on the query I found online, and I have no idea if thats even the right approach for this.
My end goal is to identify ALL users that have never made any orders. Users that have made no orders do not have a billing address or shipping address set. So therefore, I am trying to build a query that selects users with a null billing address or null shipping address and then delete them.
Many Thanks for any asssitance provided.
EDIT:
Just to clarify, the site users WooCommerce and as such there is no specific orders table in the database. meta_keys such as "billing_first_name", "shipping_first_name" and such only get populated with a value once a user has made an order for the first time. Therefore, the assumption is that a spam user would have never made an order and thus these meta_keys will be null.
Just a guess according to this post woocommerce stores orders in a posts table with post_type = 'shop_order'.
So you can try this query :
SELECT u.* FROM wv5_users u
LEFT JOIN wv5_posts p
ON u.ID = p.post_author
AND p.post_type = 'shop_order'
GROUP BY u.ID
HAVING COUNT(p.id)=0
It should return list of users never had any posts with post_type = 'shop_order'. Probably you should check what exact post_type your woocommerce uses.
Be careful if you plan to delete all those users. Some of them could be your administrators.
EDIT Sorry, I have no wordpress and woocommerce installed. Since my query does not help. Let try to go your way but a bit properly:
SELECT u.* FROM wv5_users u
LEFT JOIN wv5_usermeta m
ON u.ID = m.user_id
AND m.meta_key = 'shipping_first_name'
GROUP BY u.ID
HAVING COUNT(m.id)=0
or according to this
HAVING COUNT(m.umeta_id)=0

Change meta_value relating to specific meta_key

I have a wordpress directory theme in which a bunch of listings are about to expire. The were all created on different days. I want to batch update the whole database so that all my listings are reset for another year as of today.
They related to the table wp_postmeta and the meta_key is "alive_days" and I need to update the pertaining meta_value.
If anyone can suggest an SQL query to fix this, I will be saved a from pulling out my hair.
Thanks in advance.
LLG
See http://snag.gy/KfJfB.jpg for screengrab of the database.
Based on your response to my question, this should do the trick (take a backup of your database first, just in case):
update wp_postmeta
set meta_value = '365' -- I assume you meant that, not 356
where meta_key = 'alive_days'
The existing blanks will be updated, but since they relate to posts that no longer exist, that shouldn't matter. If you don't want to update them, you could add an extra condition (I assume they contain the empty string, not null, but the ifnull should handle that):
update wp_postmeta
set meta_value = '365'
where meta_key = 'alive_days'
and ifnull(meta_value, '') != ''

SQL Query to delete WP post using date range on a MySQL database

I am migrating a news aggregation WP site to a commercial service. We currently have over 14,000 posts on it.
We want to save the current database and reuse it under a different domain name for historical purposes.
Once we move to the new site we want to trim the WP database of all posts and related tables that are older than 01.01.2013
I know how to do a simple select where delete query.
But WP forum mods have told me that I should do an inner-join on the following tables to ensure I get everything cleaned up:
wp_postmeta
wp_term_relationships
wp_comments
wp_commentmeta
I am not familiar with inner-join. Can someone help me with this?
Not completely understanding the table structures involved, an INNER JOIN will join one table to another and return the records that match based on a certain criteria (usually joining two fields together such as a primary key and a foreign key).
To delete records from one table where some or all are in another table, the following syntax would be used:
DELETE TableName
FROM TableName
INNER JOIN AnotherTable ON TableName.id = AnotherTable.id
Here's a good visual representation of JOINS.