如何理解T-SQL中Merge语句(二)

系统 1574 0
原文: 如何理解T-SQL中Merge语句(二)

写在前面的话:上一篇写了 如何理解T-SQL中Merge语句 ,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空”的文字,大家凑合看吧。

===正文开始===

  先看下面表一(Student_Target)和表二(Student_Source)。

如何理解T-SQL中Merge语句(二)

一、When Matched部分

  执行下面SQL语句:

      MERGE INTO Student_Target AS st

USING Student_Source AS ss

ON st.Sno = ss.Sno

    WHEN MATCHED 

        THEN UPDATE SET st.Sname = ss.Sname

;


    

  执行完上面SQL语句后,现在的Student_Target表的内容应该也很容易得到,如下图:

如何理解T-SQL中Merge语句(二)

  Student_Target表中Sno=1,2的行的Sname值被Student_Source中相应的值update,不过这个结果是怎么来的呢?今天用另外一种思路来理解一下怎么得到的,我们增加一个中间过程,表述如下:

  (1)上面的SQL语句:MERGE INTO......WHEN MATCHED,可以类比成一个inner join语句:select * from Student_Target as st inner join Student_Source as ss on st.Sno=ss.Sno,内部联接后,结果如下图:

  如何理解T-SQL中Merge语句(二)

  其中红色框内是Student_Target部分,蓝色为Student_Source部分,这个图表示的是什么呢?我们可以认为后面执行的操作仅仅影响图中红色的Student_Target部分,因此,执行Then update set st.sname=ss.sname,那么原始表一Student_Target中只有 上图红色框中的部分受影响 ,即红框中Sname依次被蓝框内Sname给update了,其他行(3,'cc')不受影响,因此Student_Target最后结果为:

如何理解T-SQL中Merge语句(二)

  (2)照此思路,如果Then update set st.sname=ss.sname 改成Then delete, 自然只是红色框中部分被删除,最后Student_Target结果如下图,仅仅留下了一行。

  (3)照此思路,如果Then update set st.sname=ss.sname 改成Then insert values(ss.sno,ss.sname),会出现什么情况呢? 再看前面的红色和蓝色部分,红色部分内容不为NULL,因此无法用右边的蓝色部分给insert进去,所以应该报错,执行一下,果然报下面的错误:

如何理解T-SQL中Merge语句(二)

  现在应该明白When Matched为什么不允许有insert语句了吧,那么什么时候允许insert语句呢,接着往下看。

二、When NOT Matched BY Target部分

  前面When Matched我们通过inner join的思路进行了理解,这次When NOT Matched BY Target我们用right outer join的思路去想想,同样原始表格还是表一和表二,再次贴图如下:

如何理解T-SQL中Merge语句(二)

执行下面SQL语句:

      MERGE INTO Student_Target AS st

USING Student_Source AS ss

ON st.Sno = ss.Sno

    WHEN NOT MATCHED BY TARGET

        THEN INSERT VALUES(ss.Sno,ss.Sname)

;


    

  先不用着急看上面运行结果,我们先用right outer join的思路去梳理一下:

  (1)上面的SQL语句:MERGE INTO......WHEN NOT MATCHED BY TARGET,可以类比成一个right outer join语句:select * from Student_Target as st right outer join Student_Source as ss on st.Sno=ss.Sno,右外部联接后(你应该对right outer join 概念非常清晰吧),结果如下图:

  如何理解T-SQL中Merge语句(二)

  其中红色框内是Student_Target部分,蓝色为Student_Source部分,这个图表示的是什么呢?我们可以认为后面执行的操作仅仅影响图中红色的Student_Target部分,因此,执行Then insert values(ss.Sno,ss.Sname),那么原始表一Student_Target中只有 上图红色框中的部分受影响 ,即红框中Sno和Sname为null的依次被蓝框内Sno和Sname给insert了,这里之所以可以insert,就是因为第三行和第四行里面有null的值,因此最后Student_Target的运行结果为:

如何理解T-SQL中Merge语句(二)

  (2)照此思路,如果Then insert values(ss.Sno,ss.Sname) 改成Then delete, 自然只是红色框中部分被删除,但是红色部分的第三行和第四行是全为NULL的值,全null了自然无法删除啊,因此应该报错,运行一下,果然报错如下:

如何理解T-SQL中Merge语句(二)

  (3)照此思路,如果Then insert values(ss.Sno,ss.Sname) 改成Then update set st.Sname=ss.Sname ,同样因为全null的行会报错,因为全null无法更新啊,报错信息如下:

如何理解T-SQL中Merge语句(二)

  现在应该明白When NOT Matched BY Target为什么不允许有update和delete语句了吧。

三、When NOT Matched BY SOURCE部分

  前面When Matched我们通过inner join的思路进行了理解,When NOT Matched BY Target用right outer join的思路去理解了,这次的When not matched by source自然应该用left outer join 来理解了,具体理解过程仿照第二部分,就不详细写了,直接上结果吧:

  同样原始表格还是表一和表二,贴图如下:

如何理解T-SQL中Merge语句(二)

  (1)执行如下SQL语句:select * from Student_Target as st left outer join Student_Source as ss on st.Sno=ss.Sno,左外部联接后,结果如下图:

如何理解T-SQL中Merge语句(二)

  (2)执行下面SQL语句:

      MERGE INTO Student_Target AS st

USING Student_Source AS ss

ON st.Sno = ss.Sno

    WHEN NOT MATCHED BY SOURCE

        THEN delete

;


    

  最后Student_Target的运行结果为:

  如何理解T-SQL中Merge语句(二)

  删除了Student_Target中有而Student_Source中没有的行。

  (2)执行insert和update语句同样报错。

四、最后总结

  很佩服你竟然能看到这里,最后来一个总结吧:

(1)when matched:类比inner join去思考,可以执行update和delete操作,无法执行insert操作。

(2)when not matched by target:类比right outer join去思考,可以执行insert操作,无法执行update和delete操作。 (target表中没有(not matched),而source表中有)

(3)when not matched by source,类比left outer join去思考,可以执行delete 操作,无法执行insert和update操作。 (target表中有,而source表中没有(not matched))

 

 

备注:练习过程中用到的代码:

 

      USE testDB

GO

MERGE INTO Student_Target AS st

USING Student_Source AS ss

ON st.Sno = ss.Sno

    --WHEN MATCHED 

        --THEN UPDATE SET st.Sname = ss.Sname

        --THEN  INSERT VALUES(ss.sno,ss.sname)

    --WHEN NOT MATCHED BY TARGET

		--THEN UPDATE set st.sname=ss.sname

    --WHEN NOT MATCHED BY SOURCE 

		--THEN UPDATE set st.Sname=ss.Sname,st.Sno=ss.Sno

	

;



TRUNCATE TABLE dbo.Student_Target



TRUNCATE TABLE dbo.Student_Source



insert into Student_Target (sno,sname)values(1,'aa'),(2,'bb'),(3,'cc')



insert into Student_Source (sno,sname)values(1,'xiaoming'),(2,'xiaoli'),(4,'xiaohong'),(5,'xiaoping')



SELECT * FROM dbo.Student_Target



SELECT * FROM dbo.Student_Source





SELECT * FROM dbo.Student_Target AS st INNER JOIN dbo.Student_Source AS ss

ON st.Sno=ss.Sno



SELECT * FROM dbo.Student_Target AS st RIGHT OUTER JOIN dbo.Student_Source AS ss

ON st.Sno=ss.Sno





SELECT * FROM dbo.Student_Target AS st LEFT OUTER JOIN dbo.Student_Source AS ss

ON st.Sno=ss.Sno


    

 

如何理解T-SQL中Merge语句(二)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论