MySQL Query - avoid Duplicate Entry - mysql

The Userdatabase has usernames with "?" ending on the name. For example username: "Alex?"
Instead of deleting it I'm trying to replace this "?" with a "2" to avoid duplicate entries. The Problem is, there a still duplicate entries even with 2 at the end. I need a query, which automatically changes the 2 to 3,4,5,6,7,8 or 9 until no duplicate entry exists anymore. I was doing this manually until now, but honestly I changed over 200 lines and I guess there are more than 1000.
Some Ideas?
The Query I use:
UPDATE `userdatabase`
SET `username` = replace(`username`, "?","2")

i am not familiar mysql update syntax in detail, but if table "userdatabase" have unique id column may be possible something like that
replace(username, "?", (select count(*) from userdatabase db where db.username = username and db.id < id))

Related

MySQL Query: UPDATE and/or APPEND

I have a temporary table that I use to insert into the master db.
The temp table is named "temp_table"
The master table is "master"
I currently use the following command to update "master"
SELECT COUNT(*) FROM master;
SHOW COLUMNS FROM master;
INSERT INTO master
SELECT * FROM temp_table
ON DUPLICATE KEY UPDATE email = VALUES(email), phone = VALUES(phone)
Now, I want to be able to append field (counter) from the "temp table" into "master." The field already exists in both tables and I just want to be able to update or append it.
"counter" field in master may be empty or it may contain a number value already.
In cases where the value exists, it should append separated by a comma. Format (88,89,90)
In cases where the it's empty, it should update (88)
Thank you in advance.
I think you want:
on duplicate key update
email = values(email),
phone = values(phone),
counter = case when counter is null
then values(counter)
else concat(counter, ',', values(counter))
end
You can also phrase this with coalesce(), although the expression might be a bit more complicated to understand:
on duplicate key update
email = values(email),
phone = values(phone),
counter = concat(
coalesce(concat(counter, ','), ''),
values(counter)
)

Mysql : Query to update email with unique random value

I need to anonymize emails in DB, so I try to set a query, but I cannot find a way to generate unique random string for each.
What I have so far is :
update candidate set email = (select CONCAT(SUBSTRING(MD5(RAND()) FROM 1 FOR 15) , '#test.fr'));
But obviously the value is not unique, is that possible with a simple query?
I tried solution here : https://harrybailey.com/2015/08/mysql-roughly-random-string-generation-for-updating-rows/ but same result, I got a
Error Code: 1062. Duplicate entry '0417da5fb3d071b9bd10' for key
'email'
You can use UUID
UPDATE `candidate` SET email = CONCAT(MD5(UUID()),'#test.fr');
and if you want exactly 15 characters
UPDATE candidate SET email=CONCAT(SUBSTRING(MD5(UUID()),1,15) , '#test.fr');

Without shutting off safe update, how to write a Where clause that checks for a certain entry of a KEY column?"

Without shutting off safe update, how to write a Where clause that checks for a certain entry of a KEY column?"
'Cause basically every answer I've seen is "Shut off Safe Update", either temporarily, or permanently.
Although, Nic3500 did point me to an answer by Rudy De Volde where you search for where the key column doesn't exist.
But I'm trying to select a row by it's key column, and that isn't working.
Is Safe Update too broken to use? Or is it just the simplest solution that no one is giving ways to actually fix the error?
Although, I did copy try to update a table I created in my own database, and with:
create table z.country AS (SELECT * FROM world.country);
insert into z.country (Code, name, continent, population) values ("NHZ", "Nariza", "Antarctica", 6523);
This works:
Update WORLD.country set Name = "Noziland" where name = "Aruba" and Code <> "ABC" and Code <> "NHA";
These don't:
Update z.country set Name = "Noziland" where name = "Aruba" and Code <> "ABC" and Code <> "NHA";
Update z.country set Name = "Noziland" where Continent = "Antarctica" and Code <> "NHC" and Code <> "NHA";
EDIT: Oh, the Select * method of copying doesn't preserve primary keys! I have to add that manually!

MYSQL INSERT - "0 rows inserted". Any suggestions why is that?

INSERT INTO fields (id_region, id_fields_info, subsidy_dka, id_rents_dka, type_uses, id_rented_from, id_categories, id_farmer, id_season)
SELECT
regions.id,
fields_info.id ,
120,
rents_dka.rent_dka,
"собствена",
rented_froms.id,
categories.id_category,
farmers.id,
seasons.id
FROM regions, fields_info, rents_dka, rented_froms, categories, farmers,
seasons
WHERE
region = "Азмък" AND
field_num = 2222 AND
rent_dka = 60 AND
name = "Десислав" AND
id_category = 3 AND
name = "Десислав" AND
season = "2012-2013"
So I have these tables:
regions,
fields_info,
rents_dka,
rented_froms,
categories,
farmers,
seasons
and they are filled with some data.
I've made a form where the user fills the fields with data from these tables, that I've mentioned, and when the submit button is clicked I want to fill table FIELDS in MYSQL with ID's which I get from the data, the user had entered.
to spot the problem, I'd proceed as follow:
execute an insert without cyrillic
remove all the and
make a default insert with default values
if you get "0 rows inserted" it means that the syntax is correct, but the where clause fails to find any matching entry. I suspect the problem is the AND with the cyrillic. Remove the ANDs until the query finds some entries
I got this case when i tried to insert into a table having a column unique and my SQL had the keyword IGNORE in it :
The query:
INSERT IGNORE INTO users SET `user_id` = 7321, `name`= 'test_name', `phone` = '+188888888';
If the query didn't have IGNORE, it would throw an error (because the column user_id was set unique and I already had a row with the same user_id) but due to IGNORE keyword it just ignores the query and hence results in 0 rows inserted.
Note: I know the question asked doesn't has IGNORE key in the query, but might help someone.

Prevent auto increment on MySQL duplicate insert

Using MySQL 5.1.49, I'm trying to implement a tagging system
the problem I have is with a table with two columns: id(autoincrement), tag(unique varchar) (InnoDB)
When using query, INSERT IGNORE INTO tablename SET tag="whatever", the auto increment id value increases even if the insert was ignored.
Normally this wouldn't be a problem, but I expect a lot of possible attempts to insert duplicates for this particular table which means that my next value for id field of a new row will be jumping way too much.
For example I'll end up with a table with say 3 rows but bad id's
1 | test
8 | testtext
678 | testtextt
Also, if I don't do INSERT IGNORE and just do regular INSERT INTO and handle the error, the auto increment field still increases so the next true insert is still a wrong auto increment.
Is there a way to stop auto increment if there's an INSERT duplicate row attempt?
As I understand for MySQL 4.1, this value wouldn't increment, but last thing I want to do is end up either doing a lot of SELECT statements in advance to check if the tags exist, or worse yet, downgrade my MySQL version.
You could modify your INSERT to be something like this:
INSERT INTO tablename (tag)
SELECT $tag
FROM tablename
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
LIMIT 1
Where $tag is the tag (properly quoted or as a placeholder of course) that you want to add if it isn't already there. This approach won't even trigger an INSERT (and the subsequent autoincrement wastage) if the tag is already there. You could probably come up with nicer SQL than that but the above should do the trick.
If your table is properly indexed then the extra SELECT for the existence check will be fast and the database is going to have to perform that check anyway.
This approach won't work for the first tag though. You could seed your tag table with a tag that you think will always end up being used or you could do a separate check for an empty table.
I just found this gem...
http://www.timrosenblatt.com/blog/2008/03/21/insert-where-not-exists/
INSERT INTO [table name] SELECT '[value1]', '[value2]' FROM DUAL
WHERE NOT EXISTS(
SELECT [column1] FROM [same table name]
WHERE [column1]='[value1]'
AND [column2]='[value2]' LIMIT 1
)
If affectedRows = 1 then it inserted; otherwise if affectedRows = 0 there was a duplicate.
The MySQL documentation for v 5.5 says:
"If you use INSERT IGNORE and the row is ignored, the AUTO_INCREMENT counter
is **not** incremented and LAST_INSERT_ID() returns 0,
which reflects that no row was inserted."
Ref: http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id
Since version 5.1 InnoDB has configurable Auto-Increment Locking. See also http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html#innodb-auto-inc...
Workaround: use option innodb_autoinc_lock_mode=0 (traditional).
I found mu is too short's answer helpful, but limiting because it doesn't do inserts on an empty table. I found a simple modification did the trick:
INSERT INTO tablename (tag)
SELECT $tag
FROM (select 1) as a #this line is different from the other answer
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
LIMIT 1
Replacing the table in the from clause with a "fake" table (select 1) as a allowed that part to return a record which allowed the insert to take place. I'm running mysql 5.5.37. Thanks mu for getting me most of the way there ....
The accepted answer was useful, however I ran into a problem while using it that basically if your table had no entries it would not work as the select was using the given table, so instead I came up with the following, which will insert even if the table is blank, it also only needs you to insert the table in 2 places and the inserting variables in 1 place, less to get wrong.
INSERT INTO database_name.table_name (a,b,c,d)
SELECT
i.*
FROM
(SELECT
$a AS a,
$b AS b,
$c AS c,
$d AS d
/*variables (properly escaped) to insert*/
) i
LEFT JOIN
database_name.table_name o ON i.a = o.a AND i.b = o.b /*condition to not insert for*/
WHERE
o.a IS NULL
LIMIT 1 /*Not needed as can only ever be one, just being sure*/
Hope you find it useful
You can always add ON DUPLICATE KEY UPDATE Read here (not exactly, but solves your problem it seems).
From the comments, by #ravi
Whether the increment occurs or not depends on the
innodb_autoinc_lock_mode setting. If set to a non-zero value, the
auto-inc counter will increment even if the ON DUPLICATE KEY fires
I had the same problem but didn't want to use innodb_autoinc_lock_mode = 0 since it felt like I was killing a fly with a howitzer.
To resolve this problem I ended up using a temporary table.
create temporary table mytable_temp like mytable;
Then I inserted the values with:
insert into mytable_temp values (null,'valA'),(null,'valB'),(null,'valC');
After that you simply do another insert but use "not in" to ignore duplicates.
insert into mytable (myRow) select mytable_temp.myRow from mytable_temp
where mytable_temp.myRow not in (select myRow from mytable);
I haven't tested this for performance, but it does the job and is easy to read. Granted this was only important because I was working with data that was constantly being updated so I couldn't ignore the gaps.
modified the answer from mu is too short, (simply remove one line)
as i am newbie and i cannot make comment below his answer. Just post it here
the query below works for the first tag
INSERT INTO tablename (tag)
SELECT $tag
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
I just put an extra statement after the insert/update query:
ALTER TABLE table_name AUTO_INCREMENT = 1
And then he automatically picks up the highest prim key id plus 1.