2012-06-21 76 views
0

我有一個問題,有時候由於人爲錯誤relation_id將出現在數據庫中,關係並沒有真正的ID。MySQL - 選擇,沒有問題

SELECT relation_id 
FROM relations 
WHERE relation_id NOT 
IN (
    SELECT id 
    FROM relations 
) 

這將返回發生這種情況的字段,我想將relation_id的值切換爲NULL。

這裏是我到目前爲止有:

UPDATE `relations` SET relation_id = NULL WHERE relation_id NOT IN (SELECT id FROM relations) 

這一關當然適用於任何其他表,只有不適合的關係。有人知道解決方法嗎?我敢肯定有一種方法

+0

您確定可以使用子查詢自行更新表嗎? – Sebas

+0

MySQL說: #1093 - 您無法在FROM子句中指定目標表'關係'進行更新 – Pepijn

+0

您是通過表單還是myPhpAdmin手動輸入relations_id?通常這些都是自動編號,所以你不應該碰它們 –

回答

3

那麼,錯誤原因實際上是在錯誤消息本身中詳細描述的......您無法指定您更新的表內部的SELECT。但是誰說我們不能更深入?

UPDATE relations 
    SET relation_id = NULL 
WHERE relation_id NOT IN (
     SELECT id FROM (SELECT id FROM relations) AS take_that_sql 
); 

這裏是一個SQLFiddle玩。 )

+0

作品!感謝一堆:) – Pepijn

0

試試這個::

SELECT r1.relation_id 
FROM relations r1 
left join relations r2 on (r1.relation_id=r2.id) 
where r2.id is null 
+0

仍然得到MySQL#1093錯誤 – Pepijn

+0

你可以創建一個臨時表,然後加入並做到這一點...... 因爲它是一個mysql約束,它不會允許你更新。 –

1

這是我想嘗試:

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; 

(我不知道這是否會工作;可能引發異常,因爲關係表被引用兩次。)

如果多表更新不起作用,我會創建一個工作表,用查詢填充工作表(用於標識要更新的行)接着使用工作表運行多表更新。

這個查詢標識有一個relation_id不指向行現有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; 

你並不需要把所有的列,只有主鍵。 (我在這裏假設該主鍵是單個列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; 

附錄:

如果你正使用InnoDB,你能避免這種類型的數據完整性問題未來通過定義一個外鍵約束。例如:

ALTER TABLE relations ADD CONSTRAINT relations_FK 
FOREIGN KEY (relation_id) REFERENCES relations(id) 
ON UPDATE CASCADE ON DELETE SET NULL; 

這將禁止變更,這將導致一個relation_id具有比存在於表中的id的值以外的值的表。 (這要求id是PRIMARY KEY,並且relation_id具有相同的數據類型。)