Mysql
mysql - 如何刪除父表中的重複行並保留最低ID的一行,並用此ID替換子表中的外鍵?
我有三個表的情況:
hgn_modern_sources +----+--------------+ | id | source | +----+--------------+ | 17 | Something... | +----+--------------+ junc_modern_source_has_reference +----+------------------+------------------------+ | id | modern_source_id | location_within_source | +----+------------------+------------------------+ | 52 | 17 | 1, 1 | | 89 | 17 | 1, 1 | | 99 | 17 | 1, 1 | +----+------------------+------------------------+ hgn_picture_has_reference +----+---------------------+-------------------+ | id | modern_reference_id | picture_link | +----+---------------------+--------------------+ | 45 | 89 | /images/image1.png | | 75 | 99 | /images/image2.png | +----+---------------------+--------------------+
我的問題是如何從
junc_modern_source_has_reference
(id = 89 和 id = 99)中刪除重複項,留下 ID 最低的一行(id = 52),並將hgn_picture_has_reference
表(columnmodern_reference_id
)中的外鍵替換為左(id = 52)?該解決方案只能基於 MySQL,或 PHP + MySQL(我更喜歡)。
定義和範例數據,或者提供小提琴或定義和範例數據,如下所示,以獲得對您的問題的更多吸引力:
create table junc_modern_source_has_reference ( id int not null primary key , modern_source_id int not null ); insert into junc_modern_source_has_reference values (52,17),(89,17),(99,17); create table hgn_picture_has_reference ( id int not null primary key , modern_reference_id int not null ); insert into hgn_picture_has_reference values (45,89),(75,99);
第一步是將所有行更新為最低 id:
update hgn_picture_has_reference x set modern_reference_id = (select min(y.id) from junc_modern_source_has_reference y join junc_modern_source_has_reference z on y.modern_source_id = z.modern_source_id where x.modern_reference_id = z.id ) where exists ( select min(y.id) from junc_modern_source_has_reference y join junc_modern_source_has_reference z on y.modern_source_id = z.modern_source_id where x.modern_reference_id = z.id );
現在我們可以刪除除最低 id 之外的所有內容,這是非標準 SQL,但 MySQL 過去在引用正在修改的表時會遇到問題:
delete x.* from junc_modern_source_has_reference x join junc_modern_source_has_reference y on x.modern_source_id = y.modern_source_id and y.id < x.id ;
標準版本將類似於:
delete x.* from junc_modern_source_has_reference x where exists ( select 1 from junc_modern_source_has_reference y where x.modern_source_id = y.modern_source_id and y.id < x.id );
即,如果同一modern_source_id 有另一行具有較低ID 的行,則刪除行