昨天在写语句的时候,遇到了一个现象,其实就是使用 Cross Apply做一个拼接字符串的而已。比如

  1. CREATE TABLE GoodsCatalog
  2. (ID INT,
  3. Name NVARCHAR(50))
  4.  
  5. CREATE TABLE Goods
  6. (ID INT,
  7. GoodsCatalogID INT,
  8. Name NVARCHAR(50))
  9.  
  10. INSERT INTO GoodsCatalog
  11. ( ID, Name )
  12. VALUES ( 1,'水果'),( 2,'体育用品')
  13.  
  14. INSERT INTO Goods
  15. ( ID,GoodsCatalogID, Name )
  16. VALUES (1,1,'苹果')
  17. ,(2, 1,'香蕉')
  18. ,(3, 2,'足球')
  19. ,(4, 2,'篮球')
  20.  
  21. SELECT a.*,
  22. STUFF(B.GoodName,1,1,'') AS GoodName
  23. FROM GoodsCatalog a
  24. CROSS APPLY (SELECT '-' + b.Name
  25. FROM Goods b
  26. WHERE b.GoodsCatalogID = a.ID FOR XML PATH('')) AS B(GoodName)
  27.  
  28. /*
  29. ID Name GoodName
  30. 1 水果 苹果-香蕉
  31. 2 体育用品 足球-篮球
  32. */

很平常是吧?但是如果在 GoodsCatalog  表里面添加多2条数据呢?就会变成这样了。明明说好的 Cross Apply会将不返回生成结果集的行喔!!为啥还会这样呢!?

  1. INSERT INTO GoodsCatalog
  2. ( ID, Name )
  3. VALUES ( 3,'海鲜'),( 4,'衣服')
  4.  
  5. SELECT a.*,
  6. STUFF(B.GoodName,1,1,'') AS GoodName
  7. FROM GoodsCatalog a
  8. CROSS APPLY (SELECT '-' + b.Name
  9. FROM Goods b
  10. WHERE b.GoodsCatalogID = a.ID FOR XML PATH('')) AS B(GoodName)

  11. /*
  12. ID Name GoodName
  13. 1 水果 苹果-香蕉
  14. 2 体育用品 足球-篮球
  15. 3 海鲜 NULL
  16. 4 衣服 NULL
  17.  
  18. */
  19.  

-------------------------------------------这是描述我是一个逗比的分割线--------------------------------------------------------------------------------------------------------------

重新看了下联机文档里面的Apply 的用法

使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

就是说,无论是 Cross Apply 还是 Outer Apply 后面都是跟随一个表值函数,会与左边的输入表每一行进行交叉。所以是否返回应该看 ()里面的语句本身。

这里我又有疑问了,Goods 表里面没有 3,4 的结果啊,为什么还能显示。

这个就是函数的问题了。假如写2个表值函数对比一下就很清晰了

  1. CREATE FUNCTION TestXML
  2. (@GoodsCatalogID INT)
  3. RETURNS @TABLE TABLE
  4. (
  5. GoodName varchar(200)
  6. )
  7. AS
  8. begin
  9. ;WITH CTE(GoodName) AS
  10. (SELECT '-' + Name FROM Goods
  11. WHERE GoodsCatalogID = @GoodsCatalogID FOR XML PATH(''))
  12. INSERT INTO @TABLE (GoodName)
  13. SELECT GoodName
  14. FROM CTE
  15. RETURN
  16. END
  17.  
  18. CREATE FUNCTION TestTable
  19. (@GoodsCatalogID INT)
  20. RETURNS @TABLE TABLE
  21. (
  22. GoodName varchar(200)
  23. )
  24. AS
  25. begin
  26. INSERT INTO @TABLE (GoodName)
  27. SELECT Name FROM Goods
  28. WHERE GoodsCatalogID = @GoodsCatalogID
  29. RETURN
  30. END
  31.  
  32. SELECT *
  33. FROM dbo.TestXML(3)
  34.  
  35. /*
  36. GoodName
  37. NULL
  38. */
  39.  
  40. SELECT *
  41. FROM dbo.TestTable(3)
  42.  
  43. /*
  44. GoodName
  45. */

一个有返回,另外一个没有返回哦~~这个就知道为什么能交叉到值出来了吧。

--------------------------------------------------------------------------------------这是证明我不认真的打脸分割线------------------------------------------------------------------------------------------------------------------------

发现了这个问题,纯粹是因为对 Apply用法不清晰导致了……╮(╯_╰)╭~

为大家献丑了

使用For XML PATH 会影响Cross Apply 返回的更多相关文章

  1. sqlserver xml转表 及(cross apply与outer apply)

    一. 需求是需要把','分割的字符串转为表,便于做关联查询,于是发现可以通过xml转为表,如下: declare @XXX xml set @XXX = ' <v> <aa>1 ...

  2. SQLServer中的cross apply和FOR XML PATH

    参考: FOR XML PATH:http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html cross apply:http ...

  3. (1.3)DML增强功能-Apply、pivot、unpivot、for xml path行列转换

    深入了解行列转换请参考另一篇文章:https://www.cnblogs.com/gered/p/9271581.html 总结: 1.apply一般形式 --基本形式 SELECT a FROM d ...

  4. sql server 使用for xml path 将1列多行转换为字符串连接起来,俗称 sql 合并字符

    由于项目的原因,需要将一些记录分类汇总,但还要列出相关的明细,这样的需求我还是第一次遇到,蛋疼了,还是请求一下度娘吧.搜索一番还是有结果,请看以下例子: create table tb ([id] i ...

  5. sql server 使用for xml path 将1列多行转换为字符串连接起来

    create table tb ([id] )) insert into tb ,'aa' union all ,'bb' union all ,'cc' union all ,'dd' union ...

  6. SQL Server 2008 R2——CROSS APPLY 根据数据出现的次数和时间来给新字段赋值

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  7. SQL 关于apply的两种形式cross apply 和 outer apply

    SQL 关于apply的两种形式cross apply 和 outer apply 例子: CREATE TABLE [dbo].[Customers]( ) COLLATE Chinese_PRC_ ...

  8. SQL Server 关于CROSS APPLY 和 OUTER APPLY应用

    先看看语法: <left_table_expression>  {cross|outer} apply<right_table_expression> 再让我们了解一下appl ...

  9. Entity framewok 如何实现多条记录作为一条取出, for xml path如何实现

    http://www.myexception.cn/linq/1288046.html Entity framewok 怎么实现多条记录作为一条取出, for xml path怎么实现News表:ID ...

随机推荐

  1. Gitblit中采用Ticket模式进行协作开发

    Git目前的代码分支管理模型中,比较主要的有Git-Flow.Github Pull Request.大家日常或多或少都在用着. 在不想安装Gitlab这种重量级的环境的情况下,如果是利用git一步步 ...

  2. JPA一对多循环引用的解决

    说是解决,其实不是很完美的解决的,写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的,能否知道一二. 下面说说出现问题: 问题是这样的,当我查询一个一对多的实体的时候,工具直接就爆了,差不多我就 ...

  3. Scalaz(3)- 基础篇:函数概括化-Generalizing Functions

    Scalaz是个通用的函数式编程组件库.它提供的类型.函数组件都必须具有高度的概括性才能同时支持不同数据类型的操作.可以说,scalaz提供了一整套所有编程人员都需要的具有高度概括性的通用函数,它是通 ...

  4. java集合-ArrayList

    一.ArrayList 概述 ArrayList 是实现 List 接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口 ...

  5. .Net中的并行编程-6.常用优化策略

                本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...

  6. Servlet生命周期及工作原理

    1 Servlet生命周期Servlet 生命周期:Servlet 加载--->实例化--->服务--->销毁. init():在Servlet的生命周期中,仅执行一次init()方 ...

  7. [.NET] 使用Json.NET提供依赖注入功能(Dependence Injection)

    [.NET] 使用Json.NET提供依赖注入功能(Dependence Injection) 前言 在一些小型项目的开发情景里,系统不需要大型DI Framework所提供的:单一对象生成.生命周期 ...

  8. Material UI – Material Design CSS 框架

    Material Design 是谷歌推出的全新的设计理念,采用大胆的色彩.流畅的动画播放,以及卡片式的简洁设计.Material Design 风格的设计拥有干净的排版和简单的布局,容易理解,内容才 ...

  9. Javascript Object、Function对象

    1.Object对象 原型对象 原型是对象的一个属性,也就是prototype属性,每个对象都有这个内部属性,而且他本身也是一个对象. <script type="text/javas ...

  10. cordova 添加闪屏效果

    为项目添加SplashScreen插件 在Cordova项目目录运行: cordova plugin add apache.cordova.splashscreen 这个命令从插件git库下载插件代码 ...