Reputation: 1204
I have a problem, sometimes due to a human error a relation_id will appear in the database, of relations and there is no real id for this.
SELECT relation_id
FROM relations
WHERE relation_id NOT
IN (
SELECT id
FROM relations
)
This will return the fields where this has happened, I would like to switch the values of relation_id to NULL.
Here is what I've got so far:
UPDATE `relations` SET relation_id = NULL WHERE relation_id NOT IN (SELECT id FROM relations)
This off course works for any other table, only not for relations. Does anybody know a work-around? I'm sure there is a way
Upvotes: 0
Views: 105
Reputation: 108490
This is what I would try:
UPDATE relations r
LEFT JOIN relations s
ON r.relation_id = s.id
SET r.relation_id = NULL
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
(I'm not sure if that will work; that may raise an exception because the relations table is referenced twice.)
If the multi-table update doesn't work, I would create a work table, populate the work table with a query (that identifies the rows to be updated) and then run a multi-table update using the work table.
This query will identify rows that have a relation_id
that doesn't point to an existing id
:
SELECT r.*
FROM relations r
LEFT JOIN relations s
ON r.relation_id = s.id
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
You don't need to pull all the columns, only the primary key. (I'm assuming here that the primary key is the single column id
.)
CREATE TABLE work_table (id int PRIMARY KEY);
INSERT INTO work_table (id)
SELECT r.id
FROM relations r
LEFT JOIN relations s
ON r.relation_id = s.id
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
UPDATE relations r
JOIN work_table s
ON r.id = s.id
SET r.relation_id = NULL;
DROP TABLE work_table;
Addendum:
If you are using InnoDB, you can avoid this type of data integrity problem in the future by defining a foreign key constraint. For example:
ALTER TABLE relations ADD CONSTRAINT relations_FK
FOREIGN KEY (relation_id) REFERENCES relations(id)
ON UPDATE CASCADE ON DELETE SET NULL;
This will prohibit changes to the table which would result in a relation_id
having a value other than a value of id
that exists in the table. (This requires that id
is the PRIMARY KEY, and that relation_id has an identical datatype.)
Upvotes: 1
Reputation: 106453
Well, the reason for error is actually well-described in the error message itself... You cannot specify the table you update in the inner SELECT. But who said that we cannot go deeper?
UPDATE relations
SET relation_id = NULL
WHERE relation_id NOT IN (
SELECT id FROM (SELECT id FROM relations) AS take_that_sql
);
Here is an SQLFiddle to play with. )
Upvotes: 3
Reputation: 13465
Try this ::
SELECT r1.relation_id
FROM relations r1
left join relations r2 on (r1.relation_id=r2.id)
where r2.id is null
Upvotes: 0