當前位置:首頁 » 編程語言 » sqlmergeinto語法
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sqlmergeinto語法

發布時間: 2023-03-19 06:53:52

『壹』 DB2中merge相關用法,請舉例說明

在數據倉庫中的轉換和裝載過程中,經常會使用MERGE語句,這里簡單總結一下。MERGE語句是Oracle9i新增的語法,用來合並UPDATE和INSERT語句。通過MERGE語句,根據一張表或子查詢的連接條件對另外一張表進行查詢,連接條件匹配上的碧純銷進行UPDATE,無法匹配的執行INSERT。這個語褲漏法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE。 下面看個具體的例子: sql> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;表已創建。SQL> CREATE TABLE T1 AS 2 SELECT ROWNUM ID, OWNER, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE3 FROM DBA_TABLES;表已創建。SQL> MERGE INTO T1 USING T 2 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)3 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID4 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);6165 行已合並。SQL>悔游 SELECT ID, OWNER, OBJECT_NAME, OBJECT_TYPE FROM T2 MINUS3 SELECT * FROM T1;未選定行MERGE語法其實很簡單,下面稍微修改一下例子。SQL> DROP TABLE T;表已丟棄。SQL> DROP TABLE T1;表已丟棄。SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;表已創建。SQL> CREATE TABLE T1 AS SELECT ROWNUM ID, OWNER, TABLE_NAME FROM DBA_TABLES;表已創建。SQL> MERGE INTO T1 USING T 2 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)3 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID4 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);MERGE INTO T1 USING T*ERROR 位於第 1 行:ORA-30926: 無法在源表中獲得一組穩定的行這個錯誤是使用MERGE最常見的錯誤,造成這個錯誤的原因是由於通過連接條件得到的T的記錄不唯一。最簡單的解決方法類似:SQL> MERGE INTO T1 2 USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID FROM T GROUP BY OWNER, OBJECT_NAME) T 3 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)4 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID5 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);5775 行已合並。本文來自CSDN博客,轉載請標明出處: http://blog.csdn.net/levma/archive/2007/06/18/1656396.aspx

『貳』 SQL B表內容添加到A表

應你的要求,我來了,希望這次給你想要的解答。

我的回答是基於oracle資料庫給出的解答,
其他的資料庫,則部分實現方式需要改動

這個問題包含2個部分:一,執行的SQL語句怎麼寫;二,調用的批處理語句怎麼寫。

**********************************
首先,我使用的SQL用到了merge語句,但是它不屬於標准SQL,是oracle自己的SQL語法,如下:
merge into A using B
on A.column1=B.column1(此處可改成合適的對應條件)
when matched then
update set
A.column2=B.column2,
A.column3=B.column3...
when not matched then
insert (column1,column2...)
values (B.column1,B.column2...);
以上是完整的一句SQL語句,它完成的任務是將表B的數據合並到表A中,
這個SQL包含了2種情況的處理:
1.表B中的數據表A中已經存在時,
執行更新,定義在when matced then子句中,在update set關鍵字後,寫要更新欄位的賦值操作
2.表B中的數據表A中不存在時,
執行插入,定義在when not matched then子句中,insert後列出列名,values後是實際的欄位值
判斷是否已經存在的條件在on關鍵字後定義,一般可以使用主鍵進行判斷,例如A.id=B.id,可以使用復雜的條件如and,or,表達式等。

merge語句是oracle提供出來為數據倉庫實現方便的合並數據的,這個操作在其他資料庫中一般需要用條件判斷語句編程,如if... then... elsif... then... end if,其中加入1句insert、1句update來實現,但在oracle中,完全可以由一條merge語句就完成了。

這條merge語句你需要適應你需要的修改,完成後,
記得把它完整的保存在一個文本文件里,保存到某個路徑,比如d:\merge.txt。

**********************************
然後是批處理文件,其中要在命令行調用SQLPLUS程序,來執行以上那條SQL,如下:
ECHO ON
@ECHO BEGIN TO MERGE TABLE A B!
SQLPLUS USER/PASSWORD@ORCL_SID
@D:\merge.sql
COMMIT
EXIT
@ECHO MERGE DATA FINISHED
PAUSE

每句話的意思是:
ECHO ON 打開輸出開關
@ECHO BEGIN TO MERGE TABLE A B! @ECHO後面跟的字元是要列印在命令行里的內容,這句話執行後,命令行 會列印出BEGIN TO MERGE TABLE A B!起提示作用而已。
SQLPLUS USER/PASSWORD@ORCL_SID 在命令行里調用SQLPLUS連接oracle的命令,USER是用戶名,PASSWORD是 密碼,ORCL_SID是連接字元串,成功執行這條語句後,便已經從DOS轉入SQLPLUS環境下了。
@D:\merge.sql SQLPLUS中調用SQL腳本的方法,就是@符號跟腳本路徑就行了。
COMMIT merge操作執行後必須提交才能寫入資料庫。
EXIT 退出SQLPLUS環境,執行後命令行回到DOS環境下。
@ECHO MERGE DATA FINISHED 起提示作用,表明以上操作已執行完畢未出錯。
PAUSE 讓命令行程序執行完後不會自動關閉,而是顯示「按任意鍵繼續。。。」提示,只是給你時間看下執 行過程有無出錯提示。

把上面這段腳本保存成一個bat類型文件,如merge_ab.bat,便可以執行了。

**********************************
如果你使用的是oracle,以上方法100%可以解決你的問題,如果是其他資料庫,可以參考以上方法,思路是一樣的,只是換一種方式實現而已。

『叄』 如何替換merge into

merge into 可以寫insert 還有update語句來替換,具體段清語法可以根據具體業務彎掘需求查閱sql語法手冊來寫,很高興為你解握鬧前答,如有不解請追問。

『肆』 (急)MERGE INTO 問題

排錯方法:
1.單獨執行select B.m from B UNION ALL select C.m from C
看是否有結果,如果有結果的話,那麼 on條件有虛信問題,如果沒有結果,請檢查你的語句結果集
2.其他差卜輪的從語法上面來看沒有什麼弊數錯誤。

請樓主再確認

『伍』 SQL2008中Merge的用法

create table #ttt(id int,name nvarchar(10));
merge into #ttt t
using (select 1 as id ,'eee' as name ) b
on (t.id = b.id)
when matched then
update set t.name = b.name
when not matched then
insert(id,name) values(b.id,b.name);

『陸』 同一資料庫MERGE INTO去重插入數據。

sqlserver表結構:

sql語法:

''仿友'sql_str= u"MERGE INTO T_AGENT_PHONE_DETAIL_ a " \

u"USING (select '%s' as S_TEL, '%s' as S_MOBILE) b " \

u"ON (a.S_TEL = b.S_TEL and  a.S_MOBILE = b.S_MOBILE) " \

u"WHEN NOT MATCHED THEN " \段大孝

u"INSERT " \

u"(I_CITY_ID, S_CITY_NAME, D_IN_TIME, S_DETAIL_URL ," \

u"S_MOBILE ,S_TEL ," \

u"S_COMPANY_NAME, S_CONTACT, I_SITE_ID, S_SITE_NAME, D_COMPANY_CREATE_TIME, I_DATA_TYPE, S_COMPANY_STATUS, S_COMPANY_DESC) VALUES " \

u"(%s, '%s',getdate(),'%s','%s','%s','%s','%s', '%s', '%s', '%s' , '握稿%s', '%s', '%s');" % (

              tel,

mobile,

city_id,

city_name,

detail_url,

mobile,

tel,

company_name,

contact,

self.web_id,

self.web_name,

company_create_time,

data_type,

company_status,

company_desc

)'''

不支持macdown貼上圖片方便觀看:

『柒』 列舉一些sql高級查詢語句

1.集合操作
學習oracle中集合操作的有關語句,掌握union,union all,minus,interest的使用,能夠描述結合運算,並且能夠將多個查詢組合到一個查詢中去,能夠控制行返回的順序。
包含集合運算的查詢稱為復合查詢。見表格1-1
表1-1
Operator Returns content
UNION 由每個查詢選擇的所有不重復的行 並集不包含重復值
UNION ALL 由每個查詢選擇的所有的行,包括所有重復的行 完全並集包含重復值
INTERSECT 由每個查詢選擇的所有不重復的相交行 交集
MINUS 在第一個查詢中,不在後面查詢中,並且結果行不重復 差集

所有的集合運算與等號的優先順序相同,如果SQL語句包含多個集合運算並且沒有圓括弧明確地指定另一個順序,Oracle伺服器將以從左到右的順序計算。你應該使用圓括弧來明確地指定帶另外的集合運算的INTERSECT (相交) 運算查詢中的賦值順序。
Union all 效率一般比union高。
1.1.union和union all
UNION(聯合)運算
UNION運算返回所有由任一查詢選擇的行。用UNION運算從多表返回所有行,但除去任何重復的行。
原則 :

􀂃?被選擇的列數和列的數據類型必須是與所有用在查詢中的SELECT語句一致。列的名字不必相同。
􀂃?聯合運算在所有被選擇的列上進行。
􀂃?在做重復檢查的時候不忽略空(NULL)值。
􀂃?IN運算有比UNION運算高的優先順序。
􀂃?在默認情況下,輸出以SELECT子句的第一列的升序排序。

全聯合(UNION ALL)運算
用全聯合運算從多個查詢中返回所有行。
原則

􀂃?和聯合不同,重復的行不被過濾,並且默認情況下輸出不排序。
􀂃?不能使用DISTINCT關鍵字。
使用:
Select statement union | union all Select statement;

1.2.intersect交集操作
相交運算
用相交運算返回多個查詢中所有的公共行。 無重復行。
原則

􀂃?在查詢中被 SELECT 語句選擇的列數和數據類型必須與在查詢中所使用的所有的 SELTCT 語句中的一樣,但列的名字不必一樣。
􀂃?相交的表的倒序排序不改變結果。
􀂃?相交不忽略空值。
使用:
Select statement intersect all Select statement;

1.3. minus差集操作
相減運算
用相減運算返回由第一個查詢返回的行,那些行不出現在第二個查詢中 (第一個SELECT語句減第二個SELECT語句)。
原則

􀂃?在查詢中被SELECT語句選擇的列數和數據類型必須與在查詢中所使用的所有的SELTCT語句中的一樣,但列的名字不必一樣。
􀂃?對於MINUS運算,在WHERE子句中所有的列都必須在SELECT子句中。

集合運算的原則
?在兩個SELECT列表中的表達式必須在數目上和數據類型上相匹配
?可以用圓括弧改變執行的順序
?ORDER BY子句:–只能出現在語句的最後–從第一個SELECT語句接收列名、別名,或者位置記號

註:?除了UNION ALL,重復行自動被清除
?在結果中的列名是第一個查詢中出現的列名
?除了UNION ALL,默認情況下按升序順序輸出
2.exists和not exists的使用
2.1. exists的使用
Exists用於只能用於子查詢,可以替代in,若匹配到結果,則退出內部查詢,並將條件標志為true,傳回全部結果資料,in不管匹配到匹配不到都全部匹配完畢,使用exists可以將子查詢結果定為常量,不影響查詢效果,而且效率高。如查詢所有銷售部門員工的姓名,對比如下:
IN is often better if the results of the subquery are very small
When you write a query using the IN clause, you're telling the rule-based optimizer that you want the inner query to drive the outer query.
When you write EXISTS in a where clause, you're telling the optimizer that you want the outer query to be run first, using each value to fetch a value from the inner query.
In many cases, EXISTS is better because it requires you to specify a join condition, which can invoke an INDEX scan. However, IN is often better if the results of the subquery are very small. You usually want to run the query that returns the smaller set of results first.

In和exists對比:
若子查詢結果集比較小,優先使用in,若外層查詢比子查詢小,優先使用exists。因為若用in,則oracle會優先查詢子查詢,然後匹配外層查詢,若使用exists,則oracle會優先查詢外層表,然後再與內層表匹配。最優化匹配原則,拿最小記錄匹配大記錄。
使用in
select last_name, title
from s_emp
where dept_id in
(select id
from s_dept
where name='Sales');

使用exists
select last_name,title
from s_emp e
where exists
(select 'x' --把查詢結果定為constant,提高效率
from s_dept s where s.id=e.dept_id and s.name='Sales');
2.2 not exists的使用
與exists 含義相反,也在子查詢中使用,用於替代not in。其他一樣。如查詢不在銷售部的員工姓名
select last_name,title
from s_emp e
where not exists
(select 'x' --把查詢結果定為constant,提高效率
from s_dept s where s.id=e.dept_id and s.name='Sales');
3.with子句
9i新增語法
1.使用with子句可以讓子查詢重用相同的with查詢塊,通過select調用,一般在with查詢用到多次情況下。

2.with子句的返回結果存到用戶的臨時表空間中,只做一次查詢,提高效率。

3.有多個查詢的時候,第1個用with,後面的不用with,並且用逗號隔開。

5.最後一個with子句與下面的查詢之間不能有逗號,只通過右括弧分割,查詢必須用括弧括起來

6.如果定義了with子句,而在查詢中不使用,那麼會報ora-32035錯誤:未引用在with子句中定義的查詢名。(至少一個with查詢的name未被引用,解決方法是移除未被引用的with查詢)

7.前面的with子句定義的查詢在後面的with子句中可以使用。
With子句目的是為了重用查詢。

語法:
With alias_name as (select1), --as和select中的括弧都不能省略
alias_name2 as (select2),--後面的沒有with,逗號分割

alias_namen as (select n) –與下面的查詢之間沒有逗號
Select ….
如查詢銷售部門員工的姓名:
--with clause
with a as
(select id from s_dept where name='Sales' order by id)
select last_name,title
from s_emp where dept_id in (select * from a);--使用select查詢別名

使用with子句,可以在復雜的查詢中預先定義好一個結果集,然後在查詢中反復使用,不使用會報錯。而且with子句獲得的是一個臨時表,如果在查詢中使用,必須採用select from with查詢名,比如
With cnt as(select count(*) from table)
Select cnt+1 from al;
是錯誤的。必須是
With cnt as(select count(*) shumu from user_tables)
Select shumu+1 from cnt;
--直接引用with子查詢中的列別名。

一個with查詢的實例:
查詢出部門的總薪水大於所有部門平均總薪水的部門。部門表s_dept,員工表s_emp。
分析:做這個查詢,首先必須計算出所有部門的總薪水,然後計算出總薪水的平均薪水,再篩選出部門的總薪水大於所有部門總薪水平均薪水的部門。那麼第1步with查詢查出所有部門的總薪水,第2步用with從第1步獲得的結果表中查詢出平均薪水,最後利用這兩次的with查詢比較總薪水大於平均薪水的結果,如下:
with
--step1:查詢出部門名和部門的總薪水
dept_costs as(
select a.name,sum(b.salary) dept_total
from
s_dept a,s_emp b
where a.id=b.dept_id
group by a.name
),
--step2:利用上一個with查詢的結果,計算部門的平均總薪水
avg_costs as(
select sum(dept_total)/count(*) dept_avg
from dept_costs
)
--step3:從兩個with查詢中比較並且輸出查詢結果
select name,dept_total
from dept_costs
where
dept_total>
(
select dept_avg
from
avg_costs
)
order by name;

從上面的查詢可以看出,前面的with查詢的結果可以被後面的with查詢重用,並且對with查詢的結果列支持別名的使用,在最終查詢中必須要引用所有with查詢,否則會報錯ora-32035錯誤。

再如有這樣一個需求:一個查詢,如果查詢的結果行不滿足是10的倍數,則補空行,直到是查詢出的行數是10的倍數。例如:select * from trademark這個查詢。
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查詢比10的倍數差幾個空行
select id,name
from trademark
union all --空行加進去
select null,null --補空行
from al connect by rownum<=(select shumu from cnt); --10個中connect by可以使用子查詢
10g之前的寫法
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查詢比10的倍數差幾個空行
select id,name
from trademark
union all --空行加進去
select null,null --補空行
from all_objects where rownum<=(select shumu from cnt);--使用all_objects行比較多

4.merge into合並資料
語法:(其中as可以省略)
MERGE INTO table_name AS table_alias
USING (table|view|sub_query) AS alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET
col1 = col_val1,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)—多個列以逗號分割 //可以不指定列
VALUES (column_values);

作用:將源數據(來源於實際的表,視圖,子查詢)更新或插入到指定的表中(必須實際存在),依賴於on條件,好處是避免了多個insert和update操作。Merge是一個目標性明確的操作符,不允許在一個merge語句中對相同的行insert或update操作。這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE。例子如下:

drop table t;
CREATE TABLE T AS SELECT ROWNUM ID, A.* from DBA_OBJECTS A;

drop table t1;
CREATE TABLE T1 AS
SELECT ROWNUM ID, OWNER, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE
from DBA_TABLES;

select * from dba_objects;
select * from dba_tables;

MERGE INTO T1 USING T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--insert後面不寫表示插入全部列

MERGE INTO T1 USING T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--常見錯誤,連接條件不能獲得穩定的行,可以使用下面的用子查詢

MERGE INTO T1
USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID from T GROUP BY OWNER, OBJECT_NAME) T
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);

SELECT ID, OWNER, OBJECT_NAME, OBJECT_TYPE from T
MINUS
SELECT * from T1;

drop table subs;
create table subs(msid number(9),
ms_type char(1),
areacode number(3)
);

drop table acct;
create table acct(msid number(9),
bill_month number(6),
areacode number(3),
fee number(8,2) default 0.00);

insert into subs values(905310001,0,531);
insert into subs values(905320001,1,532);
insert into subs values(905330001,2,533);
commit;

merge into acct a --操作的表
using subs b on (a.msid=b.msid)--使用原始數據來源的表,並且制定條件,條件必須有括弧
when matched then
update set a.areacode=b.areacode--當匹配的時候,執行update操作,和直接update的語法不一樣,不需要制定表名
when not matched then--當不匹配的時候,執行insert操作,也不需要制定表名,若指定欄位插入,則在insert後用括弧標明,不指定是全部插入
insert(msid,bill_month,areacode) values(b.msid,'200702',b.areacode);

另外,MERGE語句的UPDATE不能修改用於連接的列,否則會報錯
select * from acct;
select * from subs;
--10g新特性,單個操作
merge into acct a
using subs b on(a.msid=b.msid)
when not matched then--只有單個not matched的時候,只做插入,不做更新,只有單個matched的時候,只做更新操作
insert(a.msid,a.bill_month,a.areacode) values(b.msid,'200702',b.areacode);

update acct set areacode=800 where msid=905320001;

delete from acct where areacode=533 or areacode=531;

insert into acct values(905320001,'200702',800,0.00);

--刪除重復行
delete from subs b where b.rowid<(
select max(a.rowid) from subs a where a.msid=b.msid and a.ms_type=b.ms_type and a.areacode=b.areacode);

--10g新特性,merge操作之後,只有匹配的update操作才可以,用delete where子句刪除目標表中滿足條件的行。
merge into acct a
using subs b on (a.msid=b.msid)
when MATCHED then
update set a.areacode=b.areacode
delete where (b.ms_type!=0)
when NOT MATCHED then
insert(msid,bill_month,areacode)
values(b.msid,'200702',b.areacode)
where b.ms_type=0;
--10g新特性,滿足條件的插入和更新
merge into acct a
using subs b on (a.msid=b.msid)
when MATCHED then
update set a.areacode=b.areacode
where b.ms_type=0
when NOT MATCHED then
insert(msid,bill_month,areacode)
values(b.msid,'200702',b.areacode)
where b.ms_type=0;

select * from subs where ms_type=0;

『捌』 Mysql中有類似merge into的函數嗎

1、在 SQL Server 中,int 數據類型是主要的整數數據類型。 在數據類型優先次序表中,bigint 位於 smallmoney 和 int 之間。

2、只有當參數表達式是 bigint 數據類型時,函數才返回 bigint。SQL Server 。不會自動將其它整數數據類型(tinyint、smallint 和 int)提升為 bigint。

3、int(M) 在 integer 數據類型中,M 表示最大顯示寬度。在 int(M) 中,M 的值跟 int(M) 所佔多少存儲空間並無任何關系。和數字位數也無關系 int(3)、int(4)、int(8) ,在磁碟上都是佔用 4 btyes 的存儲空間。

4、MySQL 軟體採用了雙授權政策(本詞條"授權政策"),它分為社區版和商業版,由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作為網站資料庫。

5、Index Key :MySQL是用來確定掃描的數據范圍,實際就是可以利用到的MySQL索引部分,體現在Key Length。

6、Index Filter:MySQL用來確定哪些數據是可以用索引去過濾,在啟用ICP後,可以用上索引的部分。

7、Table Filter:MySQL無法用索引過濾,回表取回行數據後,到server層進行數據過濾。

『玖』 oracle 中 merge into 在動態sql 中怎麼用

merge into table1 t
using (select a,b,c from table2)a
on (t.a=a.a and t.b=a.b)
when matched then
update set t.c=a.c
純手打 ,望採納