MySQL query to delete Joomla user with same first & last name - mysql

I know this isn't correct, but this is basically what I want to do:
delete FROM jos_users WHERE name like '<firstname>=<lastname>'
In Joomla the name field is one input and there are a lot of spam accounts that have the same first & last name - for example Uzhuzaio Uzhuzaio - that I would like to delete.
So in summary, I need a query that will delete the users from jos_users where the name field contains 2 of the same word

I think that
DELETE FROM jos_users WHERE SUBSTRING_INDEX(name, '=', 1 ) = SUBSTRING_INDEX(name, '=', -1 )
should do the trick, have you tried it?

You can use SUBSTRING_INDEX, which returns a substring before or after a certain number of occurrences of a delimiter.
In the example below, space is the delimiter, and a count of 1 will return everything to the left of the first space and a count of -1 everything on the right of the first space.
DELETE FROM jos_users WHERE
SUBSTRING_INDEX(name, " ", 1)=SUBSTRING_INDEX(name, " ", -1)
I would however perform a SELECT first, to see that there is no legitimate user in there (rare, but it could happen)
Important note: this only works if the name is in the form <name> <surname>. Multiple spaces will pose a problem. In the case of multiple spaces (e.g. <composite name> <composite name>) you should use different count values (2;-2 3;-3 etc).

Joomla by default does not have separate fields for first and last names. Most likely you have them separated by some symbol. I would recommend to define it and write a simple PHP code. At least this is what I would do.

Related

How do you remove random text in a field in a mySQL table using phpMyAdmin

I've been working with a company that is half-way around the world converting a database. They put a random set of text at the end of text inside columns in a table and I want to remove the text as easily as possible. I don't want to hand-remove thousands of entries.
For example, I have a table called "Users".
The table "users" have many different fields, but the one I want to modify is called "username"
For that column, we have the following entries:
Sam-ABC123
Bob-ABC234
Joe-ABC578
I could go into each row and change each entry so that it shows
Sam
Bob
Joe
But I have 4,000 of these just on that field alone. Quite time consuming and prone to error!
I've tried going into phpMyAdmin and do a search and replace but nothing changed.
I tried:
Find: ABC%
REPLACE: def
Column: username
Preview shows all the tables, but the original string and replacement string are the same; nothing gets replaced
I tried:
Find: ABC*
REPLACE: def
Column: username
Preview shows nothing.
Thanks in advance!
Since phpMyAdmin allows you to execute any query, why don't you just do
UPDATE users SET username = SUBSTRING(username, 0, INSTR(username, '-') - 1);
Since the dash character is used as a separator you can use a SQL query and SUBSTRING_INDEX:
UPDATE users
SET username = SUBSTRING_INDEX(username, '-', 1)
Please see a fiddle here.

Need to create a custom query

I need to clear out invalid users created by a scipted attack from the database.
The query would:
check if row name "about:me" contains "michael kors"
if yes, then set row "account_status" to "inactive"
I'm a very novice "DBA" so I'm hoping an example of a correct query in this case will help me to be able to construct others and help other users do the same.
If the column name is really about:me (a colon would be unusual), and account_status is actually a text field (not an integer indicating active/inactive), and imagining your table is named users (you didn't say), something like this would work:
update users
set account_status = 'inactive'
where `about:me` like '%michael kors%';
The backticks allow unusual characters like : to appear in the column name; the % allows varying whitespace (or other random characters) around the name when used with like; the like also allows us to match regardless of upper/lowercase in the name column.
assuming you're describing a table 'tbl' with fields 'about:me' and 'account_status', you should be able to run an UPDATE with a WHERE to do this. Something like...
UPDATE tbl
SET account_status = 'inactive'
WHERE `about:me` LIKE '%michael kors%';
Note this uses LIKE which means it's case insensitive and uses the wildcard character % to match anything containing michael kors.
Hope it helps!

mysql to update a database using UPDATE SET and TRIM(LEADING wildcard prefix in record

In my database I have a table called 'content' and a field called 'link' and there are almost 300,000 records in that table.
In the field called 'link' there are a number of records that look like this :
http://www.example.com/blah/blah/123456789/url=http://www.destination.com
Unfortunately the prefix part of the records are individually unique where the numbered portion is constant changing from 90 to 150 alpha-numeric characters
I would like to remove the prefix up to and/or including the url=
So that the only thing left in the record is :
http://www.destination.com OR
I could even work with
url=http://www.destination.com
and simply do a replace command against the "url=" part as a second mysql command.
If there was a wildcard command, this job would be much easier and I would just wildcard everything showing up in the link record between :
http://www.example.com/blah/blah/ wildcard url=
But as everyone knows... there is no such wildcard available
So it had me looking at the UPDATE, SET and TRIM(LEADING commands
UPDATE content
SET link =
TRIM(LEADING 'url=' FROM link)
But this DID NOT generate the changes I wanted
And so I took the labor intensive method of downloading the database and using a Search and Replace program to make the changes to the 44 thousand records that contained these parameters.
But I would love to find a command that I could simply pass to the database to make this simpler in the future.
Any thoughts on how to accomplish this change in the future would be greatly appreciated.
Thanks in advance ;
You can use the SUBSTRING_INDEX function:
UPDATE content SET link=SUBSTRING_INDEX( `link` , 'url=', -1 )
I have not tested it, so I would recommend you check that substring_index returns the desired string first.
Assuming that the part you want to keep always begins with 'http://' you could get the desired result string with the help of the SUBSTRING_INDEX function:
SELECT CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1)) FROM content;
and fix your table with the simple statement
UPDATE
content
SET
link = CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1));
Explanation:
SUBSTRING_INDEX with third parameter negative returns the substring from the last occurence of the needle in the second parameter to the end. Because 'http://' isn't included in the return value, we add it again.
Remark:
If you've got https:// urls too, you should be able to adapt my solution.

How to update Mysql row that has serialized data?

I have 2000 products with row that is using serialized data and I need to update specific string
this is the row name data
a:35:{s:11:"expire_days";s:3:"30d";s:12:"trial1_price";s:0:"";s:11:"trial1_days";s:0:"";s:12:"is_recurring";s:0:"";s:10:"start_date";s:0:"";s:5:"terms";s:24:"$150 for 1 Per license";s:12:"rebill_times";s:0:"";s:15:"paypal_currency";s:0:"";s:4:"##11";N;s:3:"url";s:0:"";s:8:"add_urls";s:0:"";s:4:"##12";N;s:5:"scope";s:0:"";s:5:"order";s:4:"1010";s:11:"price_group";s:1:"7";s:13:"renewal_group";s:2:"28";s:14:"need_agreement";s:0:"";s:13:"require_other";a:1:{i:0;s:0:"";}s:16:"prevent_if_other";N;s:4:"##13";N;s:19:"autoresponder_renew";s:0:"";s:16:"dont_mail_expire";s:0:"";s:13:"joomla_access";s:2:"36";s:10:"files_path";s:108:"products/Boxes8.zip|Box 8
products/Boxes9.zip|Box 9";s:14:"download_count";s:0:"";s:18:"download_unlimited";}
and only thing I need changed is
s:24:"$150 for 1 Per license";
any help is appreciated.
You should probably SELECT the row, make your changes, then UPDATE with the new value. The answer to this question may be helpful if you need to do this database side.
How to do a regular expression replace in MySQL?
If you want to replace the value of that single field with something else, you can use the following query:
UPDATE table SET col = CONCAT(
LEFT(col, LOCATE('s:24:"', col) + 5), -- up to and including the opening quote
'Now for free', -- new replacement text
SUBSTR(col, LOCATE('"', col, LOCATE('s:24:"', col)+6)) -- closing quote and everything after that
) WHERE col LIKE '%s:24:"$150 for 1 Per license"%'
Note that there is potential for trouble: if the value of one of your fields should end in 's:24:', then that combined with the closing quote would get misinterpreded as the location you're looking at. I consider this risk unlikely, but if you want to play it safe, you might want to check for that with an elaborate regular expression that can deal with quoted strings and escaped quotes.

MySQL search within the last 5 characters in a column?

My user table has a column "name" which contains information like this:
Joe Lee
Angela White
I want to search for either first name or last name efficiently. First name is easy, I can do
SELECT * FROM user WHERE name LIKE "ABC%"
But for last name, if I do
SELECT * FROM user WHERE name LIKE "%ABC"
That would be extremely slow.
So I am thinking about counting the characters of the input, for example, "ABC" has 3 characters, and if I can search only the last three characters in name column, that would be great. So I want something like
SELECT * FROM user WHERE substring(name, end-3, end) LIKE "ABC%"
Is there anything in MySQL that can do this?
Thanks so much!
PS. I cannot do fulltext because our search engine doesn't support that.
The reason that
WHERE name LIKE '%ith'
is a slow way to look for 'John Smith' by last name is the same reason that
WHERE Right(name, InStr(name, ' ' )) LIKE 'smi%'
or any other expression on the column is slow. It defeats the use of the index for quick lookup and leaves the MySQL server doing a full table scan or full index scan.
If you were using Oracle (that is, if you worked for a formerly wealthy employer) you could use function indexes. As it is you have to add some extra columns or some other helping data to accelerate your search.
Your smartest move is to split your first and last names into separate columns. Several other people have pointed out good reasons for doing that.
If you can't do that you could try creating an extra column which contains the name string reversed, and create an index on that column. That column will have, for example, 'John Smith' stored as 'htimS nhoJ'. Then you can search as follows.
WHERE nameReversed LIKE CONCAT(REVERSE('ith'),'%')
This search will use the index and be decently fast. I've had good success with it.
You're close. In MySQL you should be able to use InStr(str, substr) and Right(str, index) to do the following:
SELECT * FROM user WHERE Right(name, InStr(name, " ")) LIKE "ABC%"
InStr(name, " ") returns the index of the Space character (you may have to play with the " " syntax). This index is then used in the Right() function to search for only the last name (basically; problems arise when you have multiple names, multiple spaces etc). LIKE "ABC%" would then search for a last name starting with ABC.
You cannot use a fixed index as names that are more than 3 or less than 3 characters long would not return properly as you suggest.
However, as Zane said, it's a much better practise to use seperate fields.
If it is a MyIsam table, you may use Free text search to do the same.
You can use the REGEXP operator:
SELECT * FROM user WHERE name REGEXP "ABC$"
http://dev.mysql.com/doc/refman/5.1/en/regexp.html