MySQL實現(xiàn)merge?into四種方法代碼實例
Mysql 8.x 版本引入了 MERGE INTO 語法
Merge 語句的基本語法: MERGE INTO target_table USING source_table ON condition WHEN MATCHED THEN UPDATE SET column1 = value1, column2 = value2, ... WHEN NOT MATCHED THEN INSERT (column1, column2, ...) VALUES (value1, value2, ...);
- target_table: 要更新或插入數(shù)據(jù)的目標表。
- source_table: 包含要合并數(shù)據(jù)的來源表。
- condition: 指定用于匹配目標表和來源表數(shù)據(jù)的條件。
- WHEN MATCHED: 當目標表和來源表數(shù)據(jù)匹配時,執(zhí)行的更新操作。
- WHEN NOT MATCHED: 當目標表和來源表數(shù)據(jù)不匹配時,執(zhí)行的插入操作。
本文主要介紹將oracle中的merge into轉(zhuǎn)換成MySQL的語法
在Oracle中,可以使用merge into,但是,MySQL中不支持,可以使用以下幾種方法。
方法一:update + insert
merge其實就是不存在則insert,存在則update,所以可以把它拆分成:
update ... where exist(select 1 from ... where 條件)
insert .... where not exist(select 1 from ... where 條件)
先介紹where exists的用法
1.where exists
(1)介紹
exists和in都有過濾功能,他倆最大的差別就是in引導(dǎo)的子句只能對一個字段進行限制,比如
對id字段進行限定 select * from A where sid in (1,2,3)
但是如果我們想對多個字段進行限制,使用in就不合適了,例如
select * from A where (sid,tid) in (select sid,tid from B) 不過很可惜,上面的語句只能再DB2上執(zhí)行,SQL Server不行
此時就可以使用exists 來對多個字段進行限制了
select * from A where exists (select 1 from B where A.sid=B.sid and A.tid=B.tid)
(2)原理
exists做為where條件時,是先對where 前的主查詢詢進行查詢,然后用主查詢的結(jié)果一個一個的代入exists的查詢進行判斷,如果為真則輸出當前這一條主查詢的結(jié)果,否則不輸出。
查詢時,一般情況下,子查詢會分成兩種情況:
1.子查詢與外表的字段有關(guān)系時
select * from A where exists (select 1 from B where A.sid=B.sid and A.tid=B.tid)
它先執(zhí)行A表的查詢,再將查詢結(jié)果一條一條放到B表的條件中去查詢,如果存在,則顯示此條
2.子查詢與外表的字段沒有任何關(guān)聯(lián)
select * from A where exists (select * from B where B.id=‘條件‘)
在這種情況下,只要子查詢的條件成立,就會查詢出表1中的所有記錄,反之,如果子查詢中沒有查詢到記錄,則表1不會查詢出任何的記錄。
以上兩種方式本質(zhì)上都是對A表查詢進行過濾
2、update + insert
此種替代方式較為靈活,表可以無主鍵,自定義匹配規(guī)則。
注意:使用insert的時候需要加where not exists(select 1 from 表明 where 條件),防止重復(fù)插入
insert可以不加 where exists
方法二:replace into
語法同insert into,使用簡單,但有限制, replace into是根據(jù)主鍵去匹配,故replace into的表必須有主鍵,常用于單表更新新增。
REPLACE
的運行與INSERT
很相似。只有一點例外,假如表中的一個舊記錄與一個用于PRIMARY KEY或一個UNIQUE索引的新記錄具有相同的值,則在新記錄被插入之前,舊記錄被刪除 !刪除 !
所以還需要你有刪除數(shù)據(jù)的權(quán)限。
注意,除非表有一個PRIMARY KEY或UNIQUE索引,否則,使用一個REPLACE語句沒有意義。該語句會與INSERT相同,因為沒有索引被用于確定是否新行復(fù)制了其它的行。
需要注意的問題就是replace into的時候會刪除老記錄。如果表中有一個自增的主鍵,那么就要出問題了。
方法三:on duplicate key update
在MYSQL中有語句 insert into ... on duplicate key update...
INSERT INTO table (id, name, age) values (1, 'yourname', 18) ON DUPLICATE KEY UPDATE name='yourname', age=18;
id字段是主鍵或者UNIQUE索引。上述語句的作用是:
如果id = 1
這條記錄是不存在的,那么執(zhí)行INSERT INTO
語句。
如果id = 1
在數(shù)據(jù)庫中是存在的,那么執(zhí)行UPDATE
命令,此時這條語句相當于:
UPDATE table SET name='yourname', age=18 WHERE id=1;
再如果 age 字段也是UNIQUE的,相當于
UPDATE table SET name='yourname' WHERE id=1 OR age=18 LIMIT 1;
執(zhí)行UPDATE語句的條件是INSERT語句的執(zhí)行會造成唯一鍵的重復(fù)。
通常,應(yīng)該盡量避免對帶有多個唯一關(guān)鍵字的表使用ON DUPLICATE KEY
子句。
還可以這樣寫:
INSERT INTO table (SELECT id, 'hisname' as name FROM table WHERE id >= 3) ON DUPLICATE KEY UPDATE name=VALUES(name);
這種方法還可以用來批量執(zhí)行UPDATE
操作(因為單條UPDATE
語句只能執(zhí)行一種update操作)
方法四:創(chuàng)建存儲過程
CREATE PROCEDURE name() if exists(select 1 from 表 where ID = @ID) begin UPDATE 表 SET XX= XX WHERE ID = @ID end else begin INSERT 表 VALUES(XX...) end
總結(jié)
到此這篇關(guān)于MySQL實現(xiàn)merge into四種方法的文章就介紹到這了,更多相關(guān)MySQL實現(xiàn)merge into內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql利用mysqlbinlog命令恢復(fù)誤刪除數(shù)據(jù)的實現(xiàn)
這篇文章主要介紹了mysql利用mysqlbinlog命令恢復(fù)誤刪除數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03mysql連接的空閑時間超過8小時后 MySQL自動斷開該連接解決方案
MySQL 的默認設(shè)置下,當一個連接的空閑時間超過8小時后,MySQL 就會斷開該連接,而 c3p0 連接池則以為該被斷開的連接依然有效。在這種情況下,如果客戶端代碼向 c3p0 連接池請求連接的話,連接池就會把已經(jīng)失效的連接返回給客戶端,客戶端在使用該失效連接的時候即拋出異常2012-11-11Win 8或以上系統(tǒng)下MySQL最新版5.7.17(64bit ZIP綠色版)安裝部署教程
這篇文章主要為大家詳細介紹了Win 8或以上系統(tǒng)下MySQL最新版5.7.17 64bit ZIP綠色版安裝部署教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05SQL優(yōu)化老出錯,那是你沒弄明白MySQL解釋計劃用法
本篇文章講的是SQL優(yōu)化老出錯,那是你沒弄明白MySQL解釋計劃用法,有興趣的小伙伴速度來看看吧,希望本篇文章能夠幫助到你2021-11-11