I have three tables :
user_details
user_badges
badges
I have a query where I use "insert ignore into" command to insert the badge id from badges and user id from user_details into user_badge.
$username=$_SESSION['username'];
$getlife="SELECT * FROM user_details WHERE username='$username'";
$getlifedb=mysqli_query($db, $getlife);
while ($row=mysqli_fetch_array($getlifedb)){
if($row['fullife'] == '1'){
$full="INSERT IGNORE INTO user_badge(user_id, badge_id)
SELECT u.user_id, b.badge_id
FROM user_details as u
CROSS JOIN badges as b
WHERE u.user_id='$id'
AND b.badge_id='8'";
mysqli_query($db, $full) or die(mysqli_error($db));
}
}
Below is the picture of user_badge table:
But every time I execute the command, the insert ignore doesnt work, but instead it just insert a field again. Can someone help me fix this issue.
INSERT IGNORE only works when a duplicating field in table is being set as UNIQUE. user_id in table user_badge is not set to UNIQUE, that's why it duplicates it.
If you need to have multiple badges for an user, but those are not supposed to be duplicated, you need to set the pair to be UNIQUE, -> UNIQUE(user_id,user_badge)
Without UNIQUE, INSERT IGNORE doesn't make any sense, as it doesn't throw any errors when inserting the same records.
From msql documentation "Use the INSERT IGNORE command rather than the INSERT command. If a record doesn't duplicate an existing record, then MySQL inserts it as usual. If the record is a duplicate, then the IGNORE keyword tells MySQL to discard it silently without generating an error."
I agree fully with #Flush Thunder. If you do not care having duplicate entries just use INSERT instead, but for what you´re writing this is not the case.
Apparently, your user must have a unique id, while may have several badges which is consistent with a unique user.
Related
I have a table with 2 columns, userid and messageid. I am updating it automatically through a php script, but I can't get a working insert statement. I don't mind if there are duplicates of userid, or duplicates of messageid (in fact there should be duplicates of both), I just don't want any duplicate of the same combination of userid and messageid. Is there any way to write a query that will do this for me, or do I have to handle it at the php level?
I've probably tried 20 different queries that I found on here and google, but have not gotten it right. This was the last thing I tried:
INSERT INTO interests_join (userid, interestid)
VALUES (1, 4)
WHERE NOT EXISTS
(SELECT userid, interestid FROM interests_join WHERE userid = 1 AND interestid = 4)
You can add a UNIQUE KEY, sql will refuse to insert a new row that is a duplicate of an existing one.
ALTER TABLE `interests_join` ADD UNIQUE `row` (`userid`, `interestid`);
Then you'll have to check from PHP if the query was successful or not (error #1062). You can't apply the key if there are duplicate rows, you have to remove them first .
I need to add data to a MySQL database like that:
Person:
pId, nameId, titleId, age
Name:
nameId, name
Title:
titleId, title
I don't want to have any names or title more then once in the db so I didn't see a solution with LAST_INSERT_ID()
My approach looks like that:
INSERT IGNORE INTO Name(name) VALUES ("Peter");
INSERT IGNORE INTO Title(title) VALUES ("Astronaut");
INSERT INTO Person(nameId, titleId, age) VALUES ((SELECT nameId FROM Name WHERE name = "Peter"), (SELECT nameId FROM Name WHERE name = "Astronaut"), 33);
But I guess that's a quite dirty approach!?
If possible I want to add multiple persons with one query and without having anything more then one times in db.
Is this possible in a nice way? Thanks!
You could put title and name as two columns of your table and then:
set one UNIQUE index on each column if you don"t want to have two titles or two names identical in the DB
or set an UNIQUE index on (title,name) if you don't want to have two entries having both the same name and the same title.
If you really want to have separate tables, you could do as you suggested in your post, but wrapping all your insert statements in a TRANSACTION to allow rollback if you detect a duplicate somewhere.
See Design dilemma: If e-mail address already used, send e-mail "e-mail address already registered", but can't because can't add duplicate to table which appear to be exactly the same problem, but having name & email instead of name & titles.
START TRANSACTION;
INSERT INTO title(value) VALUES ("Prof.");
SELECT LAST_INSERT_ID() INTO #title_id;
-- Instead of using user-defined variable,
-- you should be able to use the last_insert_id
-- equivalent from the host language MySQL driver.
INSERT INTO username(value) VALUES ("Sylvain");
SELECT LAST_INSERT_ID() INTO #username_id;
-- Instead of using user-defined variable,
-- you should be able to use the last_insert_id
-- equivalent from the host language MySQL driver.
INSERT INTO account(username_id, email_id) VALUES (#username_id,#title_id);
COMMIT;
See LAST_INSERT_ID()
A third solution would be to SELECT before doing you insert to see in the entry are already present. But personally I wouldn't push to the check-before-set approach at the very least, this will require an extra query which is mostly superfluous if you use correctly indexes.
Following on from this: SQL INSERT from SELECT and the correct answer marked there.
I will need to be able to also check whether the row already exists, also by using the username. So would I delete and then insert or is there a better way?
And if it is delete, how do I say DELETE FROM table WHERE UserID = do the username select here
Thanks
If delete then you can use:
DELETE a FROM Avatar a LEFT JOIN User u ON a.UserID=u.UserID WHERE u.UserName='theusername'
Try REPLACE INTO instead of INSERT INTO. If the UserID is specified and is the primary key for the table, this will overwrite the row whose UserID matches what you insert.
To answer your sub-question, it would be DELETE FROM table WHERE UserID IN (SELECT UserID ...)
Side note: StackOverflow is really not an appropriate venue for learning basic SQL. If you read up first, your questions will be better and the answers correspondingly more useful.
Coming from the other question where you're doing an "insert from select", I assume you want to not insert the row that already have entries for the keys you're attempting to insert. I also assume that it's giving you some error like "duplicate key found".
With those assumptions in mine, the fix is simple: add the IGNORE keyword after INSERT, so you're query looks something like this:
INSERT IGNORE... //rest of query
i'm currently using a replace into statement, I have a unique field which will cause it to UPDATE rather than INSERT if it finds a duplicate...
Problem is if it finds a duplicate i can't get to update on a few columns, it just wipes the lot.
Is there a similar "one statement" method where I can just UPDATE what I want?
I've found merge into but don't undertsnad the first bit about merge into table using table
You're going to want to use the INSERT...ON DUPLICATE KEY UPDATE syntax.
http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html
Here's an example that will try to create a record with an id, birthday, and name. If a record with the id field exists, it will do the update specified. The table has lots of other fields like email address, zip code, etc. I want to leave those fields alone if I update. (REPLACE INTO would lose any of that data if I didn't include it in the REPLACE INTO statement.)
INSERT INTO user (userid,birthday,first_name,last_name)
VALUES (1234,'1980-03-07','Joe','Smith')
ON DUPLICATE KEY UPDATE
birthday = '1980-03-07',
first_name = 'Joe',
last_name = 'Smith';
I'm using MySQL 4.1. Some tables have duplicates entries that go against the constraints.
When I try to group rows, MySQL doesn't recognise the rows as being similar.
Example:
Table A has a column "Name" with the Unique proprety.
The table contains one row with the name 'Hach?' and one row with the same name but a square at the end instead of the '?' (which I can't reproduce in this textfield)
A "Group by" on these 2 rows return 2 separate rows
This cause several problems including the fact that I can't export and reimport the database. On reimporting an error mentions that a Insert has failed because it violates a constraint.
In theory I could try to import, wait for the first error, fix the import script and the original DB, and repeat. In pratice, that would take forever.
Is there a way to list all the anomalies or force the database to recheck constraints (and list all the values/rows that go against them) ?
I can supply the .MYD file if it can be helpful.
To list all the anomalies:
SELECT name, count(*) FROM TableA GROUP BY name HAVING count(*) > 1;
There are a few ways to tackle deleting the dups and your path will depend heavily on the number of dups you have.
See this SO question for ways of removing those from your table.
Here is the solution I provided there:
-- Setup for example
create table people (fname varchar(10), lname varchar(10));
insert into people values ('Bob', 'Newhart');
insert into people values ('Bob', 'Newhart');
insert into people values ('Bill', 'Cosby');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Adam', 'Sandler');
-- Show table with duplicates
select * from people;
-- Create table with one version of each duplicate record
create table dups as
select distinct fname, lname, count(*)
from people group by fname, lname
having count(*) > 1;
-- Delete all matching duplicate records
delete people from people inner join dups
on people.fname = dups.fname AND
people.lname = dups.lname;
-- Insert single record of each dup back into table
insert into people select fname, lname from dups;
-- Show Fixed table
select * from people;
Create a new table, select all rows and group by the unique key (in the example column name) and insert in the new table.
To find out what is that character, do the following query:
SELECT HEX(Name) FROM TableName WHERE Name LIKE 'Hach%'
You will se the ascii code of that 'square'.
If that character is 'x', you could update like this:(but if that column is Unique you will have some errors)
UPDATE TableName SET Name=TRIM(TRAILING 'x' FROM Name);
I'll assume this is a MySQL 4.1 random bug. Somes values are just changing on their own for no particular reason even if they violates some MySQL constraints. MySQL is simply ignoring those violations.
To solve my problem, I will write a prog that tries to resinsert every line of data in the same table (to be precise : another table with the same caracteristics) and log every instance of failures.
I will leave the incident open for a while in case someone gets the same problem and someone else finds a more practical solution.