T-SQL中jion操作
--创建学生表 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操作的更多相关文章
- sql 中延时操作
select 1; WAITFOR DELAY '00:00:30'; select 2; --执行完第一个之后会 延时 30秒,才会执行第二个sql
- 关于sql中日期操作
select * from account where DAYOFWEEK('2019-11-30') =7 limit 10 DAYOFWEEK对应结果: 周日:1 周一:2 周二:3 周三:4 ...
- SQL Server 中同时操作的例子:
在SQL 中同一逻辑阶段的操作是同时发生的. 先有一个例子做为带入: declare @x as int =1;declare @y as int =2;set @x=@y;set @y=@x;sel ...
- SQL导入txt以及SQL中的时间格式操作
原文:SQL导入txt以及SQL中的时间格式操作 MySQL中导入txt的指令为: load data local infile "路径名称" into table "表 ...
- SQL点滴33—SQL中的字符串操作
原文:SQL点滴33-SQL中的字符串操作 计算字符串长度len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写lower() ...
- Unity中对SQL数据库的操作
在Unity中,我们有时候需要连接数据库来达到数据的读取与储存.而在.NET平台下,ADO.NET为我们提供了公开数据访问服务的类.客户端应用程序可以使用ADO.NET来连接到数据源,并查询,添加,删 ...
- SQL中的join操作总结(非常好)
1.1.1 摘要 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接.外联接和交叉联接等.如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的 ...
- 在Sql Server触发器中判断操作是Insert还是Update还是Delete
在Sql Server触发器中判断操作是Insert还是Update还是Delete DECLARE @IsInsert bit, @IsUpdate bit, @IsDelete ...
- SQL中union运算操作的理解
在SQL中,对于并运算,可以使用union关键字. 例如: SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FRO ...
随机推荐
- 避开WebForm天坑,拥抱ASP.Net MVC吧
有鹏友在如鹏网的QQ群中提了一个问题: 请问,在ASP.Net中如何隐藏一个MenuItem,我想根据不同的权限,对功能菜单进行隐藏,用style不行. 如果要仅仅解答这个问题,很好解答,答案很简单: ...
- [Voice communications] 让音乐响起来
本系列文章主要是介绍 Web Audio API 的相关知识,由于该技术还处在 web 草案阶段(很多标准被提出来,至于取舍需要等待稳定版文档来确定,草案阶段的文档很多都会被再次编辑甚至重写.全部删除 ...
- 将整数转换成二进制的java小程序
首先我们知道,将整数转换成二进制是将整数除二取余将最后除得的数和得到的余数从下向上写,组成得到的二进制数. java程序实现如下: public class ChangeToErjinzhi { pu ...
- zendframework 2 链接数据库
相对于zf1,来说,zf2让我们对于数据库这方面的操作我的个人感觉是对于字段起别名简单了,但是对数据库的操作虽然配置写好的就基本不需要动了,但是还是比1的配置要繁琐, 还是那句话,大家可以去看看源码. ...
- NanoProfiler - 适合生产环境的性能监控类库 之 实践ELK篇
上期回顾 上一期:NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇 上次介绍了NanoProfiler的大数据分析理念,一晃已经时隔一年多了,真是罪过! 有朋友问到何时开源的问题 ...
- 将不确定变成确定~Uri文本文件不用浏览器自动打开,而是下载到本地
回到目录 这个标题有点长,简单来说就是,对于一个文件下载来说,是否可以提示用户,让它去保存,而不是将它在浏览器中打开,在浏览器中打开有个致命问题,那就是,如果你的页面编码和文件的编码不一致时,打开的就 ...
- EF架构~有时使用SQL更方便
回到目录 在进行统计时,尤其是按月进行统计,由于我们采用的时间是一个2015-12-12日这种,所以在linq你无法进行拆分,你拆分了在发到SQL时也会报错,因为SQL那边更新不需要你.net的方法, ...
- fir.im Weekly - iOS 保持界面流畅的技巧
生命不息,coding 不止.本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码分享,产品 UI 设计的好文章,还有一些程序员成长的 Tips,希望 ...
- salesforce 零基础学习(四十二)简单文件上传下载
项目中,常常需要用到文件的上传和下载,上传和下载功能实际上是对Document对象进行insert和查询操作.本篇演示简单的文件上传和下载,理论上文件上传后应该将ID作为操作表的字段存储,这里只演示文 ...
- 每天一个linux命令(13):less 命令
less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...