--创建学生表
create table Students(
    sno       nvarchar(10)    not null primary key,
    name     nvarchar(30)    not null,
    gender    nchar(1)        check(gender = '男' or gender='女') default('男')
)
go

insert into Students(sno,name,gender) values('S001','张三','男')
insert into Students(sno,name,gender) values('S002','李四','男')
insert into Students(sno,name,gender) values('S003','王五','女')
insert into Students(sno,name,gender) values('S004','赵六','女')
go
--创建课程表
create table Course(
    cno        nvarchar(10)    not null primary key,
    name      nvarchar(30)    not null,
)
go
insert into Course(cno,name)values('C001','数学')
insert into Course(cno,name)values('C002','语文')
insert into Course(cno,name)values('C003','英语')
insert into Course(cno,name)values('C004','物理')
go
--创建成绩
create table Score(
    sno    nvarchar(10)    not null,
    cno    nvarchar(30)    not null,
    score int
)
go

insert into Score values ('S001','C001',91);
insert into Score values ('S002','C001',93);
insert into Score values ('S002','C002',94);
insert into Score values ('S002','C003',95);
insert into Score values ('S003','C001',96);
insert into Score values ('S003','C002',97);
insert into Score values ('S003','C003',98);
--为了测试full join,特意插入一条学号不存在的数据
insert into Score values ('XXXX','C003',98);

/***************************************************************inner join*******************************************************/
--查询学生的学号,姓名,对应的课程名称,以及分数
select ST.sno,ST.name,CO.name,SC.score
  from Students ST
 inner join Score SC on ST.sno = SC.sno
 inner join Course CO on SC.cno = CO.cno
sno        name                           name                           score
---------- ------------------------------ ------------------------------ -----------
S001       张三                             数学                             91
S002       李四                             数学                             93
S002       李四                             语文                             94
S002       李四                             英语                             95
S003       王五                             数学                             96
S003       王五                             语文                             97
S003       王五                             英语                             98

(7 行受影响)

/***************************************************************right join*******************************************************/
--查询所有学生对应的课程信息
select ST.name,SC.cno  from Students ST
left join Score SC on ST.sno=SC.sno
/***************************************************************left join*******************************************************/
select ST.name,SC.cno  from Score SC
right join Students ST on ST.sno=SC.sno

name                           cno
------------------------------ ------------------------------
张三                             C001
李四                             C001
李四                             C002
李四                             C003
王五                             C001
王五                             C002
王五                             C003
赵六                             NULL

(8 行受影响)

/***************************************************************full join*******************************************************/
--查询所有的学生以及分数信息
select * from  Students ST
full join Score SC  on ST.sno=SC.sno
--outer可以省略,等同于如下查询
select * from Students ST full outer join Score SC on ST.sno=SC.sno

sno        name                           gender sno        cno                            score
---------- ------------------------------ ------ ---------- ------------------------------ -----------
S001       张三                             男      S001       C001                           91
S002       李四                             男      S002       C001                           93
S002       李四                             男      S002       C002                           94
S002       李四                             男      S002       C003                           95
S003       王五                             女      S003       C001                           96
S003       王五                             女      S003       C002                           97
S003       王五                             女      S003       C003                           98
S004       赵六                             女      NULL       NULL                           NULL
NULL       NULL                            NULL   XXXX       C003                            98

(9 行受影响)

/***************************************************************cross join(笛卡尔积)*******************************************************/
--查询“缺考”的学生信息(有课程,无成绩的信息)
--利用cross join,生成学生与课程的笛卡尔积,也就是所有学生对应的所有课程信息
--然后跟成绩表做左联接,如果成绩不存在,则说明“缺考”
select *
  from (select ST.sno, ST.name as Sname, CO.cno, CO.name as CName
          from Students ST
         cross join Course CO) T
  left join Score SC on T.cno = SC.cno
                    and T.sno = SC.sno
 where SC.cno is null
sno        Sname                          cno        CName                          sno        cno                            score
---------- ------------------------------ ---------- ------------------------------ ---------- ------------------------------ -----------
S001       张三                             C002       语文                             NULL       NULL                           NULL
S001       张三                             C003       英语                             NULL       NULL                           NULL
S001       张三                             C004       物理                             NULL       NULL                           NULL
S002       李四                             C004       物理                             NULL       NULL                           NULL
S003       王五                             C004       物理                             NULL       NULL                           NULL
S004       赵六                             C001       数学                             NULL       NULL                           NULL
S004       赵六                             C002       语文                             NULL       NULL                           NULL
S004       赵六                             C003       英语                             NULL       NULL                           NULL
S004       赵六                             C004       物理                             NULL       NULL                           NULL

(9 行受影响)

--cross join:指定两个表的叉积。返回相同的行
--这里的cross join就是笛卡尔积
select ST.sno, ST.name as Sname, CO.cno, CO.name as CName
          from Students ST
         cross join Course CO

--或者是不指定连接条件,查询出来的也是笛卡尔积
select ST.sno, ST.name as Sname, CO.cno, CO.name as CName
          from Students ST, Course CO

--或者是cross apply
select ST.sno, ST.name as Sname, CO.cno, CO.name as CName
          from Students ST
          cross apply Course CO

/***************************************************************Apply运算符*******************************************************/
--APPLY 运算符的左操作数和右操作数都是表表达式。
--这些操作数之间的主要区别是,right_table_source 可以使用表值函数,从 left_table_source 获取一个列作为函数的参数之一。
--left_table_source 可以包括表值函数,但不能以来自 right_table_source 的列作为参数。

--查询学生分数最高的两科成绩
select ST.name, T.cno, T.score
  from Students ST
 cross apply (select top 2 *
                from Score SC
               where ST.sno = SC.sno
               order by SC.score desc) T
name                           cno                            score
------------------------------ ------------------------------ -----------
张三                             C001                           91
李四                             C003                           95
李四                             C002                           94
王五                             C003                           98
王五                             C002                           97

(5 行受影响)

--查询所有学生分数最高的两科成绩,成绩少于两科或者没有成绩的,显示为空
select ST.name, isnull(T.cno,'不存在') as 课程号, isnull(T.score,0) as 分数
  from Students ST
 outer apply (select top 2 *
                from Score SC
               where ST.sno = SC.sno
               order by SC.score desc) T
name                           课程号                            分数
------------------------------ ------------------------------ -----------
张三                             C001                           91
李四                             C003                           95
李四                             C002                           94
王五                             C003                           98
王五                             C002                           97
赵六                             不存在                            0

(6 行受影响)

通俗地说,cross apply 与表或者是表值函数连接时,右边的表或者表示函数依赖于左边的结果集
就类似于在外层遍历左边的表,
依次获取左边的表中的数据作为参数,传递到右边的查询中(或者函数中)作为查询条件,得到的结果集再与外层的结果集做连接,然后输出结果
咋一看,跟普通的join没啥区别,要注意的是:普通的表之间的关联是根据关联字段,只要关联字段满足条件,就输出

而cross apply右边的结果集是根据左边每一行数据的关联条件来做输入的,
把左边结果的一行中的某个字段,作为参数,获取一个结果集,让这个结果集跟左边的表做连接
其实根据上面的查询,很容易理解,查询出每个人分数最高的两门课程的成绩,
就是遍历学生信息表中的“每个人”(SNO)
------->作为参数传递到cross(outer) apply子查询中
------->得到成绩的结果集
------->跟学生信息表关联,输出

其中,cross apply 和 outer apply的区别就类似于inner join与left join
决定了是否输出左边结果集中存在,右边结果集中不存在数据的情况下,是否输出的问题

T-SQL中jion操作的更多相关文章

  1. sql 中延时操作

    select 1; WAITFOR DELAY '00:00:30'; select 2; --执行完第一个之后会 延时 30秒,才会执行第二个sql

  2. 关于sql中日期操作

    select * from account where  DAYOFWEEK('2019-11-30') =7 limit 10 DAYOFWEEK对应结果: 周日:1 周一:2 周二:3 周三:4 ...

  3. SQL Server 中同时操作的例子:

    在SQL 中同一逻辑阶段的操作是同时发生的. 先有一个例子做为带入: declare @x as int =1;declare @y as int =2;set @x=@y;set @y=@x;sel ...

  4. SQL导入txt以及SQL中的时间格式操作

    原文:SQL导入txt以及SQL中的时间格式操作 MySQL中导入txt的指令为: load data local infile "路径名称" into table "表 ...

  5. SQL点滴33—SQL中的字符串操作

    原文:SQL点滴33-SQL中的字符串操作 计算字符串长度len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写lower() ...

  6. Unity中对SQL数据库的操作

    在Unity中,我们有时候需要连接数据库来达到数据的读取与储存.而在.NET平台下,ADO.NET为我们提供了公开数据访问服务的类.客户端应用程序可以使用ADO.NET来连接到数据源,并查询,添加,删 ...

  7. SQL中的join操作总结(非常好)

    1.1.1 摘要 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接.外联接和交叉联接等.如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的 ...

  8. 在Sql Server触发器中判断操作是Insert还是Update还是Delete

    在Sql Server触发器中判断操作是Insert还是Update还是Delete DECLARE    @IsInsert bit,    @IsUpdate bit,    @IsDelete  ...

  9. SQL中union运算操作的理解

    在SQL中,对于并运算,可以使用union关键字. 例如: SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FRO ...

随机推荐

  1. 《理解 ES6》阅读整理:函数(Functions)(六)Purpose of Functions

    明确函数的双重作用(Clarifying the Dual Purpose of Functions) 在ES5及更早的ES版本中,函数调用时是否使用new会有不同的作用.当使用new时,函数内的th ...

  2. 初识selenium--百度实例录制

    Selenium 是一个web的自动化测试工具,不少学习功能自动化的朋友首选的就是Selenium,它相比QTP有许多优点(QTP笔者由于种种原因暂未使用过O(∩_∩)O哈!): ①Selenium是 ...

  3. 【ContextMenu】DataContext不自动更新

    参考资料 http://www.orcode.com/article/Presentation_20147076.html      问题现象 通过绑定集合至ContextMenu的ItemsSour ...

  4. 冲刺阶段 day12

    项目进展 周二我们将专业管理部分又继续做了完善,之前漏掉的几项功能也都在熟能生巧中编写的越来越顺畅,但还差最后一点数据库部分没能实现,我们会尽快完成. 存在问题 还是与数据库的连接上出现问题,部分不能 ...

  5. Java提高篇(三四)-----fail-fast机制

    在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList: 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证.快速失 ...

  6. [nRF51822] 3、 新年也来个总结——图解nRF51 SDK中的Button handling library和FIFO library

    :本篇是我翻译并加入自己理解的nRF51 SDK中按钮相关操作的库和先进先出队列库.虽然是nRF51的SDK,但是通过此文你将更多地了解到在BSP(板级支持)上层嵌入式程序或OS的构建方法. 1.按钮 ...

  7. IOS Socket 03-建立连接与登录

    1. 搭建python服务器 这里我们用到python服务器Socket Server.如何运行Server?下面介绍 1)通过百度云下载文件 http://pan.baidu.com/s/1i5yb ...

  8. jmx完整示例

    很早就开始去了解这个了,不过一直都是皮毛,基本概念明白,具体api几乎一无不知... 认真看了几篇文章,做了测试,终于有所了解 参考 入门级别: http://www.cnblogs.com/agou ...

  9. 写js写傻了,明天研究一下异步

    在html某元素上绑定一个click事件,该事件是一个执行事件很长的函数,比如执行几十亿或几百亿次加法,那么在这个函数执行的过程中,其他元素绑定的事件,是如何触发的呢,异步触发还是同步,触发时是怎么执 ...

  10. GUID相关知识

      全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符.GUID主要用于在拥有多个节点.多台计算机的网络或系统中.在理想 ...