SQL Server 一些关键字详解(二)
1.LEFT JOIN 容易让人误解的地方
背景:因为在网上搜了下 LEFT JOIN 和 OUTER APPLY 的区别,时发现,有的网友解释为:
1) A left join B 的连接的记录数与A表的记录数同.
2) LEFT JOIN 左连接 -- 显示左表所有存在的记录 记录数=左表.
像这些说法都不对的.根据我测试得出的结论应该是:
LEFT JOIN 返回结果数 >= 左表的记录数
网上有部分人的解释都漏了 大于(>) 的那部分,后我找了下感觉比较权威的答案:
在W3School中的解释为:
LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。
在百度百科解释为:
left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的。换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID)。B表记录不足的地方均为NULL。
好像都没有明显的说到:当左表的数据,在右表匹配到多条记录的情况,这样就很容易让人误解.下面我做了个例子,
比如有个类别表(Category)内容如下:
还有个类别明细表(CategoryDetail)内容如下:
那好现在测试开始:
可以看到,本来左表(Category)里面只有三条数据的,使用了LEFT JOIN之后带出了四条数据,其中多出的就是对应左表(Category)匹配右表(CategoryDetail)数据时,出现多条数据的情况.
2.使用各种 JOIN 时需要注意的地方
一般我们使用JOIN 时都是直接一个表名, ON 后面加条件如下:
但是有时候也会这么写:
这时候好像没什么问题,好的,要是再加个条件 把两个表关联起来,那么问题来了,假如我是这样写:
SELECT * FROM dbo.Category a
LEFT JOIN (SELECT * FROM dbo.CategoryDetail b WHERE b.Id=1 AND b.CategoryId=a.Id) AS c ON 1=1
这时候就就会很郁闷的发现报错了,报错如下:
为什么会出现: 無法繫結多重部分(Multi-Part) 識別碼"a.Id"。 错呢?我发现凡是适用JOIN时使用 括号() 然后在里面加select 语句时如果在使用外面的字段,就会报这个问题:
比如使用CROSS JOIN:
使用RIGHT JOIN:
使用INNER JOIN:
使用FULL JOIN:
总结:使用JOIN关键字时,如果不是直接JOIN一个表名而是,使用圆括号() 里面加select 语句时,关联外部表字段时,就会出现: 無法繫結多重部分(Multi-Part) 識別碼 问题.
附注
附帶SQL腳本一份:
/****** Object: Table [dbo].[CategoryDetail] Script Date: 08/19/2015 19:46:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[CategoryDetail](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CategoryId] [int] NULL,
[Cry] [varchar](50) NULL,
CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[CategoryDetail] ON
INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (1, 1, N'喵')
INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'汪')
INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (3, 2, N'汪汪')
SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF
/****** Object: Table [dbo].[Category] Script Date: 08/19/2015 19:46:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Category](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Category] ON
INSERT [dbo].[Category] ([Id], [Name]) VALUES (1, N'Cat')
INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog')
INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger')
SET IDENTITY_INSERT [dbo].[Category] OFF
SQL Server 一些关键字详解(二)的更多相关文章
- SQL Server 一些关键字详解(一)
1.CROSS APPLY 和OUTER APPLY MSDN解释如下(个人理解不是很清晰): 使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数.表值函数作为右输入,外 ...
- MS SQL Server 数据库连接字符串详解
MS SQL Server 数据库连接字符串详解 原地址:http://blog.csdn.net/jhhja/article/details/6096565 问题 : 超时时间已到.在从池中获取连接 ...
- SQL Server表分区详解
原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆 ...
- sql server 存储过程的详解
SqlServer存储过程详解 1.创建存储过程的基本语法模板: if (exists (select * from sys.objects where name = 'pro_name')) dro ...
- SQL Server 性能优化详解
故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...
- SQL server T-SQL索引详解
SQL索引在数据库优化中占有一个非常大的比例,一个好的索引的设计,可以让sql语句查询效率提高很多被. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引的主要目的是提高T-SQL系统 ...
- Sql Server之数据类型详解
数据类型是一种属性,用于指定对象可保存的数据的类型,SQL Server中支持多种数据类型,包括字符类型.数值类型以及日期类型等.数据类型相当于一个容器,容器的大小决定了装的东西的多少,将数据分为 ...
- JDBC连接SQL Server 2005步骤详解
一.设置SQL Server服务器: 1.“开始” → “程序” → “Microsoft SQL Server 2005” → “配置工具” → “SQL Server Configurati ...
- [转]MS SQL Server 数据库连接字符串详解
http://blog.csdn.net/jackiehome/article/details/8668121 问题 : 超时时间已到.在从池中获取连接之前超时时间已过.出现这种情况可能是因为所有池连 ...
随机推荐
- python(二)拾遗
1.int 系统内部自动执行的 a=123>>>>a=int(123)>>>>a=_init_(123) 外部调用 a 2 b=a.bit_length ...
- 【测试】trunc和round的区别
trunc是截断:round是四舍五入:下面通过一个例子具体看一下trunc和round的不同 SQL),trunc() from dual; TRUNC() TRUNC() ------------ ...
- Add, remove, shuffle and sort
To deal cards, we would like a method that removes a card from the deck and returns it. The list met ...
- SVN中取消冲突conflict
在SVN update代码出现冲突的时候,可以先右键点击SVN commit,在打开的窗口中单击红框内区域: 然后,再一次点击edit->mark as resolved,然后删除代码中> ...
- oracle 闪回技术
oracle默认不启动闪回数据库 如果需要启动闪回数据库,数据库需要设置为归档模式,并启用恢复区. 1.查看是否启动闪回删除 SQL> show parameter recyclebin; NA ...
- 动态链接库(dll) __declspec(dllimport) __declspec(dllexport)
一. __declspec(dllexport) Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib ...
- 华为OJ平台——将真分数分解为埃及分数
题目描述: 分子为1的分数称为埃及分数.现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数.如:8/11 = 1/2+1/5+1/55+1/110. 输入: 输入一个真分数, ...
- Android控件大全(二)——Toolbar
1.隐藏Actionbar 代码中设置:requestWindowFeature(Window.FEATURE_NO_TITLE) //如果Activity是继承自AppCompatActiv ...
- Windows API学习---插入DLL和挂接API
插入DLL和挂接API 在Microsoft Windows中,每个进程都有它自己的私有地址空间.当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址.你的进程不能创建一个其引用 ...
- 八、Linux下的网络服务器模型
服务器设计技术有很多,按使用的协议来分有TCP服务器和UDP服务器,按处理方式来分有循环服务器和并发服务器. 在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求,对服务端的程序就提 ...