使用For XML PATH 会影响Cross Apply 返回

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

CREATE TABLE GoodsCatalog
(ID INT,
    Name NVARCHAR(50))    

CREATE TABLE Goods
(ID INT,
    GoodsCatalogID INT,
    Name NVARCHAR(50))  

INSERT INTO GoodsCatalog
        ( ID, Name )
VALUES  ( 1,‘水果‘),( 2,‘体育用品‘)

INSERT INTO Goods
        ( ID,GoodsCatalogID, Name )
VALUES  (1,1,‘苹果‘)
       ,(2, 1,‘香蕉‘)
       ,(3, 2,‘足球‘)
       ,(4, 2,‘篮球‘)

SELECT a.*,
        STUFF(B.GoodName,1,1,‘‘) AS GoodName
    FROM GoodsCatalog a
        CROSS APPLY (SELECT ‘-‘ + b.Name
                            FROM Goods b
                                WHERE b.GoodsCatalogID = a.ID FOR XML PATH(‘‘)) AS B(GoodName)

/*
ID    Name    GoodName
1    水果    苹果-香蕉
2    体育用品    足球-篮球
*/

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

INSERT INTO GoodsCatalog
        ( ID, Name )
VALUES  ( 3,‘海鲜‘),( 4,‘衣服‘)

SELECT a.*,
        STUFF(B.GoodName,1,1,‘‘) AS GoodName
    FROM GoodsCatalog a
        CROSS APPLY (SELECT ‘-‘ + b.Name
                            FROM Goods b
                                WHERE b.GoodsCatalogID = a.ID FOR XML PATH(‘‘)) AS B(GoodName)

/*
ID    Name    GoodName
1    水果    苹果-香蕉
2    体育用品    足球-篮球
3    海鲜    NULL
4    衣服    NULL

*/

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

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

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

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

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

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

CREATE FUNCTION TestXML
(@GoodsCatalogID INT)
RETURNS @TABLE TABLE
(
    GoodName varchar(200)
)
AS
begin
    ;WITH CTE(GoodName) AS
    (SELECT ‘-‘ + Name FROM Goods
        WHERE GoodsCatalogID = @GoodsCatalogID FOR XML PATH(‘‘))
    INSERT INTO @TABLE (GoodName)
    SELECT GoodName
        FROM CTE
    RETURN
END

CREATE FUNCTION TestTable
(@GoodsCatalogID INT)
RETURNS @TABLE TABLE
(
    GoodName varchar(200)
)
AS
begin
    INSERT INTO @TABLE (GoodName)
    SELECT  Name FROM Goods
        WHERE GoodsCatalogID = @GoodsCatalogID
    RETURN
END

SELECT *
    FROM dbo.TestXML(3)

/*
GoodName
NULL
*/

SELECT *
    FROM dbo.TestTable(3)

/*
GoodName
*/

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

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

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

为大家献丑了

时间: 2024-08-11 05:44:47

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

SQLServer中的cross apply和FOR XML PATH

参考: FOR XML PATH:http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html cross apply:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html 应用: FOR XML PATH,可以在group by 语句中,合并非group字段,例如:查询每个学生对应的课程(多个课程使用逗号隔开) cross apply,可以查询A表的同时

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

例子: CREATE TABLE [dbo].[Customers]( [customerid] [char](5) COLLATE Chinese_PRC_CI_AS NOT NULL, [city] [varchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL, PRIMARY KEY CLUSTERED ( [customerid] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]

灵活运用 SQL SERVER FOR XML PATH

FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作.那么以一个实例为主. 一.FOR XML PATH 简单介绍              那么还是首先来介绍一下FOR XML PATH ,假设现在有一张兴趣爱好表(hobby)用来存放兴趣爱好,表结构如下: 接下来我们来看应用FOR XML PATH的查询结果语句如下: SELECT * FROM @hobby FO

使用 CROSS APPLY 与 OUTER APPLY 连接查询

?  前言 日常开发中遇到多表查询时,首先会想到 INNER JOIN 或 LEFT OUTER JOIN 等等,但是这两种查询有时候不能满足需求.比如,左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配.貌似,INNER JOIN 或 LEFT OUTER JOIN 不能很好完成.但是 CROSS APPLY 与 OUTER APPLY 可以,下面用示例说明. 1.   示例一 ?  有两张表:Student(学生表)和 Score(成绩表),数据如下: 1)   查询每个

SQL FOR XML PATH 和 Stuff 用法

sql stuff 用法 1.作用 删除指定长度的字符,并在指定的起点处插入另一组字符. 2.语法 STUFF ( character_expression , start , length ,character_expression ) 3.示例 以下示例在第一个字符串 abcdef 中删除从第 2 个位置(字符 b)开始的三个字符,然后在删除的起始位置插入第二个字符串,从而创建并返回一个字符串 SELECT STUFF('abcdef', 2, 3, 'ijklmn')GO 下面是结果集 a

行转列(FOR XML PATH)

SELECT (SELECT ac.ColName+',' FROM T1 AS ac FOR XML PATH('')) AS ColName, (SELECT ac.colTitle+',' FROM T1 AS ac FOR XML PATH('')) AS colTitle 行转列(FOR XML PATH),布布扣,bubuko.com

for xml path

在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据 示例:

使用for xml path 分组查询

SELECT OLevel, WorkOrgID, WorkOrgName, PlanNum, PlanFinishNum, PlanUnFinishNum, PlanCanceledNum, PlanChangedNum, OrtherNum, PlanTime, ActualTime, RIGHT(PlanIDs,LEN(PlanIDs)-1) AS PlanIDs FROM (SELECT ( CASE MIN(Parent) WHEN 'E13744A1-7E2C-42E8-8E7B-4

sql FOR XML PATH('')

alter function test() Returns nvarchar(max) As Begin Declare @avg nvarchar(max) Declare @str nvarchar(max) Set @str=( Select ','+yuanshidanhao from Aj_Jibenxinxi Where convert(nvarchar(max),id) in (1,2,6) FOR XML PATH('') ) Return @str End sql FOR XM