在 SQL Server 中,
使用
以下是一个简单的示例,演示如何使用
假设我们有一个名为
SELECT E.EmployeeName, D.DepartmentName, D.DepartmentDescription FROM Employees E CROSS APPLY ( SELECT DepartmentName, DepartmentDescription FROM Departments WHERE DepartmentID = E.DepartmentID ) D;
在这个示例中,
总之,
使用实例代码:
with cte as ( select *, cast(substring(month_info,7,3) as int) month_index --相对new_refreshdate的月份差值,用于计算具体的yyyymm from (select new_totalreturnplanId,new_refreshdate, ownerid, isnull(convert(char(10) ,new_collectiondate_n, 120),'')+'|'+isnull(cast(new_collectionamount_n as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n as varchar),'') month_0, isnull(convert(char(10) ,new_collectiondate_n1, 120),'')+'|'+isnull(cast(new_collectionamount_n1 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n1 as varchar),'') month_1, isnull(convert(char(10) ,new_collectiondate_n2, 120),'')+'|'+isnull(cast(new_collectionamount_n2 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n2 as varchar),'') month_2, isnull(convert(char(10) ,new_collectiondate_n3, 120),'')+'|'+isnull(cast(new_collectionamount_n3 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n3 as varchar),'') month_3, isnull(convert(char(10) ,new_collectiondate_n4, 120),'')+'|'+isnull(cast(new_collectionamount_n4 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n4 as varchar),'') month_4, isnull(convert(char(10) ,new_collectiondate_n5, 120),'')+'|'+isnull(cast(new_collectionamount_n5 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n5 as varchar),'') month_5, isnull(convert(char(10) ,new_collectiondate_n6, 120),'')+'|'+isnull(cast(new_collectionamount_n6 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n6 as varchar),'') month_6, isnull(convert(char(10) ,new_collectiondate_n7, 120),'')+'|'+isnull(cast(new_collectionamount_n7 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n7 as varchar),'') month_7, isnull(convert(char(10) ,new_collectiondate_n8, 120),'')+'|'+isnull(cast(new_collectionamount_n8 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n8 as varchar),'') month_8, isnull(convert(char(10) ,new_collectiondate_n9, 120),'')+'|'+isnull(cast(new_collectionamount_n9 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n9 as varchar),'') month_9, isnull(convert(char(10) ,new_collectiondate_n10, 120),'')+'|'+isnull(cast(new_collectionamount_n10 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n10 as varchar),'') month_10, isnull(convert(char(10) ,new_collectiondate_n11, 120),'')+'|'+isnull(cast(new_collectionamount_n11 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n11 as varchar),'') month_11, isnull(convert(char(10) ,new_collectiondate_n12, 120),'')+'|'+isnull(cast(new_collectionamount_n12 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n12 as varchar),'') month_12, isnull(convert(char(10) ,new_collectiondate_n13, 120),'')+'|'+isnull(cast(new_collectionamount_n13 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n13 as varchar),'') month_13, isnull(convert(char(10) ,new_collectiondate_n14, 120),'')+'|'+isnull(cast(new_collectionamount_n14 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n14 as varchar),'') month_14, isnull(convert(char(10) ,new_collectiondate_n15, 120),'')+'|'+isnull(cast(new_collectionamount_n15 as varchar),'')+'|'+isnull(cast(new_collectionamount_org_n15 as varchar),'') month_15 from new_totalreturnplanBase) SourceTable --1.先把字段拼接起来 UNPIVOT --2.列转行 (collection_info FOR month_info IN (month_0, month_1,month_2,month_3,month_4,month_5,month_6,month_7,month_8,month_9,month_10,month_11,month_12,month_13,month_14,month_15)) AS UnpivotTable ) select new_totalreturnplanId,new_refreshdate,ownerid, CONVERT(VARCHAR(6),dateadd(MONTH,month_index,new_refreshdate), 112) yyyymm, d.[1] as new_collectiondate, d.[2] as new_collectionamount, d.[3] as new_collectionamount_org from cte c CROSS APPLY--将拼接的collection_info拆分成多列 ( SELECT [1], [2],[3] FROM (select value,(ROW_NUMBER() over (order by (select 1))) num from string_split(c.collection_info,'|')) SourceTable PIVOT ( max(value) FOR num IN ([1],[2],[3]) ) AS PivotTable )d
这里 CROSS APPLY 的是一个拼接字符串string_split而得来的表.
心得:
1.通常我们需要得到多个字段的值一般会想到通过join关联表返回,CROSS APPLY某种意义上和表连接的功能相同;
2.当我们不合适或者无法使用表连接查询一个表的多个字段时(如上,根本没有可以关联的表),你不应该重复使用子查询来查询这些字段,而是使用CROSS APPLY,将需要通过子查询得到的所有字段统一通过CROSS APPLY查出来,实现子查询后置,而不是在select后重复使用子查询每个字段查询一次.