Ø  前言

日常开发中遇到多表查询时,首先会想到 INNER JOIN 或 LEFT OUTER JOIN 等等,但是这两种查询有时候不能满足需求。比如,左表一条关联右表多条记录时,我需要控制右表的某一条多条记录跟左表匹配。貌似,INNER JOIN 或 LEFT OUTER JOIN 不能很好完成。但是 CROSS APPLY 与 OUTER APPLY 可以,下面用示例说明。

1.   示例一

Ø  有两张表:Student(学生表)和 Score(成绩表),数据如下:

1)   查询每个学生最近两次的考试成绩

1.   先试下 INNER JOIN

1)   SQL 代码

SELECT T1.StudentNo, T1.Name, T2.ExamScore, T2.ExamDate FROM Student AS T1

INNER JOIN Score AS T2 ON T1.StudentNo = T2.StudentNo

2)   结果:

3)   咦,不对,这不是我想要的结果。

2.   再看看 CROSS APPLY

1)   SQL 代码

SELECT T1.StudentNo, T1.Name, T2.ExamScore, T2.ExamDate FROM Student AS T1

CROSS APPLY(

SELECT TOP 2 * FROM Score AS T

WHERE T1.StudentNo = T.StudentNo

ORDER BY T.ExamDate DESC

) AS T2

2)   结果:

3)   嗯,这次对了,并且还是按照“考试时间”倒序排序的。

2)   查询每个学生最近两次的考试成绩,没有参加考试的同学成绩补 null

1.   先试下 LEFT OUTER JOIN

1)   SQL 代码

SELECT T1.StudentNo, T1.Name, T2.ExamScore, T2.ExamDate FROM Student AS T1

LEFT OUTERJOIN Score AS T2 ON T1.StudentNo = T2.StudentNo

2)   结果:

3)   咦,不对,这又不是我想要的结果。

2.   再看看 OUTER APPLY

1)   SQL 代码

SELECT T1.StudentNo, T1.Name, T2.ExamScore, T2.ExamDate FROM Student AS T1

OUTER APPLY(

SELECT TOP 2 * FROM Score AS T

WHERE T1.StudentNo = T.StudentNo

ORDER BY T.ExamDate DESC

) AS T2

2)   结果:

3)   嗯,这次对了,不但按照“考试时间”倒序排序的,而且没有考试的同学也被查出来了。

Ø  总结

1.   理解 CROSS APPLY 与 OUTER APPLY(个人理解)

1)   CROSS APPLY 的意思是“交叉应用”,在查询时首先查询左表,然后右表的每一条记录跟左表的当前记录进行匹配。匹配成功则将左表与右表的记录合并为一条记录输出;匹配失败则抛弃左表与右表的记录。(与 INNER JOIN 类似)

2)   OUTER APPLY 的意思是“外部应用”,与 CROSS APPLY 的原理一致,只是在匹配失败时,左表与右表也将合并为一条记录输出,不过右表的输出字段为 null。(与 LEFT OUTER JOIN 类似)

2.   CROSS APPLY 与 INNER JOIN 的区别

1)   CROSS APPLY 可以根据当前左表的当前记录去查询右表,但是 INNER JOIN 不可以,INNER JOIN 是根据左表的当前记录匹配右表整个结果集。

2)   两者都是匹配成功才输出。

3.   OUTER APPLY 与 LEFT OUTER JOIN 的区别

1)   它们和(CROSS APPLY 与 INNER JOIN)类似。

2)   只是两者都是匹配失败也会输出。

4.   使用场景:

1)   一个商品有多张图片,但是只想取最近的一张图片跟商品匹配。

5.   总结一句话:右表可以是有条件的跟左表的记录匹配,而条件的值可以来至于左表。

使用 CROSS APPLY 与 OUTER APPLY 连接查询的更多相关文章

  1. SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)

    先简单了解下cross apply的语法以及会产生什么样的结果集吧!示例表: SELECT * FROM tableA CROSS APPLY tableB 两张表直接连接,不需要任何的关联条件,产生 ...

  2. SQLServer连接查询之Cross Apply和Outer Apply的区别及用法

    https://blog.csdn.net/wikey_zhang/article/details/77480118 先简单了解下cross apply的语法以及会产生什么样的结果集吧! 示例表: S ...

  3. SqlSever 使用 CROSS APPLY 与 OUTER APPLY 连接查询

    前言 日常开发中遇到多表查询时,首先会想到 INNER JOIN 或 LEFT OUTER JOIN 等等,但是这两种查询有时候不能满足需求.比如,左表一条关联右表多条记录时,我需要控制右表的某一条或 ...

  4. SQL SERVER使用 CROSS APPLY 与 OUTER APPLY 连接查询

    概述 CROSS APPLY 与 OUTER APPLY 可以做到:      左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配的情况. 有两张表:Student(学生表)和 S ...

  5. SQL 关于apply的两种形式cross apply 和 outer apply(转)

    转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...

  6. SQL关于apply的两种形式cross apply和outer apply(转载)

    SQL 关于apply的两种形式cross apply 和 outer apply   apply有两种形式: cross apply 和 outer apply   先看看语法:   <lef ...

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

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

  8. 转:SQL 关于apply的两种形式cross apply 和 outer apply

    原文地址:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html SQL 关于apply的两种形式cross apply 和 out ...

  9. cross apply 和 outer apply

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

随机推荐

  1. mysql安转过程中出现的问题! Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exis

    net start mysql启动失败,报错信息如上,因缺少mysql这个库 所以跳过 在my.ini中添加 --skip-grant-tables 再启动mysql 然后进入mysql 倒入一个从其 ...

  2. Linux登录那点事

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 我们登录linux的时候基本上不太关注上面的这个提示,其实这个还是有点文章的 ...

  3. springAop 使用@Around,@After等注解时,代码运行两边的问题

    springAop使用@Around,@After等注解时,代码运行两边的问题 将@Component注解删掉就好了

  4. js 获取当前时间 年月日

    var datetime = new Date(); var year = datetime.getFullYear(); var month = datetime.getMonth() + 1 &l ...

  5. vue router获取整条路径参数

    $route.path 当前路由对象的路径,如'/vi$route.query 请求参数,如/foo?user=1获取到query.user = 1$route.router 所属路由器以及所属组件信 ...

  6. JS时间戳转换成时间格式

    TimeNow: function (val) { var date = new Date(val); var Y = date.getFullYear(); var m = date.getMont ...

  7. quartz 每天0点5分开始,以后每隔15分钟启动一次,23:50停止

    quartz 每天0点5分开始,以后每隔15分钟启动一次,23:50停止,这个表达式怎么写? 5 用quartz做定时器,要求达到这样的效果每天0点5分开始,以后每隔15分钟启动一次,23:50停止不 ...

  8. ElasticSearch6.5.0 【script_lang not supported】

    执行代码:[就是想根据条件更新]把品牌为LiNing的都改成Cat. UpdateByQueryRequestBuilder updateByQuery = UpdateByQueryAction.I ...

  9. (线段判交的一些注意。。。)nyoj 1016-德莱联盟

    1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们 ...

  10. (简单贪心) 发工资咯:) hdu2021

    发工资咯:) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...