簡體   English   中英

具有自連接的困難的MySQL更新查詢

[英]Difficult MySQL Update Query with Self-Join

我們的網站上有清單。 我們使用具有以下結構的連接表將我們的成員與這些各種清單連接起來:

CREATE TABLE `connections` (
  `cid1` int(9) unsigned NOT NULL DEFAULT '0',
  `cid2` int(9) unsigned NOT NULL DEFAULT '0',
  `type` char(2) NOT NULL,
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`cid1`,`cid2`,`type`,`cid3`),
  KEY `cid1` (`cid1`,`type`),
  KEY `cid2` (`cid2`,`type`)
);

我們遇到的問題是,當我們不得不不時合並重復的列表時,我們還需要更新成員連接,並且一直在使用以下查詢,如果一個成員同時連接到兩個列表,該查詢就會中斷:

update connections set cid2=100000
where type IN ('MC','MT','MW') AND cid2=100001;

我不知道如何解決以下問題:

update connections set cid2=100000
where type IN ('MC','MT','MW') AND cid2=100001 AND cid1 NOT IN (
    select cid1 from connections
    where type IN ('MC','MT','MW') AND cid2=100000
);

當我嘗試運行該查詢時,出現以下錯誤:

ERROR 1093 (HY000): You can't specify target table 'connections' for update in FROM clause

這是一些示例數據。 請注意,cid1 = 10025925的更新沖突

+----------+--------+------+---------------------+---------------------+
| cid1     | cid2   | type | created             | updated             |
+----------+--------+------+---------------------+---------------------+
| 10010388 | 100000 | MC   | 2010-08-05 18:04:51 | 2011-06-16 16:26:17 |
| 10025925 | 100000 | MC   | 2010-10-31 09:21:25 | 2010-10-31 16:21:25 |
| 10027662 | 100000 | MC   | 2011-06-13 16:31:12 | NULL                |
| 10038375 | 100000 | MW   | 2011-02-05 05:32:35 | 2011-02-05 19:51:58 |
| 10065771 | 100000 | MW   | 2011-04-24 17:06:35 | NULL                |
| 10025925 | 100001 | MC   | 2010-10-31 09:21:45 | 2010-10-31 16:21:45 |
| 10034884 | 100001 | MC   | 2011-01-20 18:54:51 | NULL                |
| 10038375 | 100001 | MC   | 2011-02-04 05:00:35 | NULL                |
| 10041989 | 100001 | MC   | 2011-02-26 09:33:18 | NULL                |
| 10038259 | 100001 | MC   | 2011-05-07 13:34:20 | NULL                |
| 10027662 | 100001 | MC   | 2011-06-13 16:33:54 | NULL                |
| 10030855 | 100001 | MT   | 2010-12-31 20:40:18 | NULL                |
| 10038375 | 100001 | MT   | 2011-02-04 05:00:36 | NULL                |
+----------+--------+------+---------------------+---------------------+

我希望有人可以建議運行上述查詢的正確方法。 提前致謝!

一種可能的方法是對子查詢使用臨時表,然后從臨時表中選擇。 但是,如果您需要執行許多此類查詢,則效率可能會迅速下降。

create temporary table subq as select cid1 from connections where type IN ('MC','MT','MW') AND cid2=100000

update connections set cid2=100000 where type IN ('MC','MT','MW') AND cid2=100001 AND cid1 NOT IN (select cid1 from subq);

查詢錯誤的原因是因為在MySQL中,您無法從試圖在同一查詢中進行更新的表中進行選擇。

使用UPDATE IGNORE避免重復沖突。

我認為您應該嘗試閱讀INSERT ON DUPLICATE KEY。 這樣的想法是,您對總是創建DUPLICATE沖突的INSERT查詢進行構架,然后UPDATE部分將發揮其作用。

我在想類似以下內容的方法,但是我不確定100%之前和之后的數據如何確定准確性。 想法是在子查詢的where子句和排除cid1不能匹配的where將表自身連接起來。

update connections c1 left outer join connections c2
 on (c2.cid2 = 100000 and c2.type in ('MC','MT','MW') and c1.cid1 != c2.cid1)
 set c1.cid2 = 100000
 where c1.type in ('MC', 'MT', 'MW') and c1.cid2=100001 and c2.cid1 is null;

據我所知,它將起作用。 我使用了您的create table (減去主鍵中的cid3 ),並確保我有2行具有相同的cid1和不同的cid2 (一個為100000,另一個為100001),並且該語句僅影響了1行。

UPDATE connections cn1
LEFT JOIN connections cn2 ON cn1.cid1 != cn2.cid1
    AND cn2.type IN ('MC','MT','MW')
    AND cn2.cid2=100000
SET cn1.cid2=100000
WHERE cn1.TYPE IN ('MC','MT','MW') 
    AND cn1.cid2=100001 
    AND cn2.cid1 IS NULL -- i.e. there is no matching record

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM