• 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 后面加条件如下:

     

      但是有时候也会这么写:

      这时候好像没什么问题,好的,要是再加个条件 把两个表关联起来,那么问题来了,假如我是这样写:

     

    1 SELECT * FROM dbo.Category a
    2 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腳本一份:

     

     

     

     1 /****** Object:  Table [dbo].[CategoryDetail]    Script Date: 08/19/2015 19:46:37 ******/
     2 SET ANSI_NULLS ON
     3 GO
     4 SET QUOTED_IDENTIFIER ON
     5 GO
     6 SET ANSI_PADDING ON
     7 GO
     8 CREATE TABLE [dbo].[CategoryDetail](
     9     [Id] [int] IDENTITY(1,1) NOT NULL,
    10     [CategoryId] [int] NULL,
    11     [Cry] [varchar](50) NULL,
    12  CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED 
    13 (
    14     [Id] ASC
    15 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    16 ) ON [PRIMARY]
    17 GO
    18 SET ANSI_PADDING OFF
    19 GO
    20 SET IDENTITY_INSERT [dbo].[CategoryDetail] ON
    21 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (1, 1, N'')
    22 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'')
    23 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (3, 2, N'汪汪')
    24 SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF
    25 /****** Object:  Table [dbo].[Category]    Script Date: 08/19/2015 19:46:36 ******/
    26 SET ANSI_NULLS ON
    27 GO
    28 SET QUOTED_IDENTIFIER ON
    29 GO
    30 SET ANSI_PADDING ON
    31 GO
    32 CREATE TABLE [dbo].[Category](
    33     [Id] [int] IDENTITY(1,1) NOT NULL,
    34     [Name] [varchar](50) NULL,
    35  CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
    36 (
    37     [Id] ASC
    38 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    39 ) ON [PRIMARY]
    40 GO
    41 SET ANSI_PADDING OFF
    42 GO
    43 SET IDENTITY_INSERT [dbo].[Category] ON
    44 INSERT [dbo].[Category] ([Id], [Name]) VALUES (1, N'Cat')
    45 INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog')
    46 INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger')
    47 SET IDENTITY_INSERT [dbo].[Category] OFF
    View Code

     

     

     

     

     

     

     

     

  • 相关阅读:
    actionscript3.0 的一些小技巧
    Flash 安全沙箱的意义
    明明连上了网,但是打不开网页
    关于电脑上可用内存太小的问题
    AS3 Starling 学习杂谈 (一) Quad类
    更新flash builder4,6 的AIR版本
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    微信小程序开发指南合集 各类组件用法技巧
    微信小程序视频教程合集 附带源码、PPT下载
  • 原文地址:https://www.cnblogs.com/lyaom/p/4743292.html
Copyright © 2020-2023  润新知