数据库查询中的左连接及注意事项

 上班闲来无事,上网灌水累了,于是决定self study一会,找了一份公司的数据库培训资料,翻翻看看

 翻到join查询一块,突然想起以前开发时,碰到的一个左连接的问题,于是,在优快云查找旧贴,整理了一下.

 
 我们在查询的时候,有三种join类型:内连接、外连接和交叉连接。
 内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用
的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。
 外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)
和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹
配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的
数据行。
    交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的
数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑
运算符等构成。
   无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接
连接。例如:
   SELECT p1.pub_id,p2.pub_id,p1.pr_info
FROM pub_info AS p1 INNER JOIN pub_info AS p2
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

    好像扯远了,我们要讲的是左外连接(LEFT OUTER JOIN或LEFT JOIN)


    采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外
连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

 可以简单的理解为,左表中的记录,只要满足where 条件,就一定要被抓出来,不管是否join 成功

 
 比如现在的表情况是这样的:

 表A  
   
  A     AA        
  1     22  
  2     33  
  3     44  
   
  表B  
   
  A     BB   CC  
  1     23   33  


 左连接的写法一般有两种,(A做左表)

 1) select   A.A   B.BB   FROM   A,B   WHERE   A.A   *=   B.A  

    2)   select   A.A   B.BB   FROM   A   Left  Join   b   ON   A.A   =   B.A  


  这是OK的,返回的结果是 3条记录

 1,23  
    2,  
    3,  

 后面两条的BB 字段为NULL

 
 但是如果我们后面加一个where 条件,这两个查询的结果就不一样了

 select   A.A   B.BB   FROM   A,B   WHERE   A.A   *= B.A AND B.CC   =   33  
  那么这样,还是返回三条记录  
  1,23  
  2,  
  3,  
  
 但是  
  select   A.A   B.BB   FROM   A   Left   Join   b   ON   A.A = B.A where  B.CC   =   33  
  但是这样,就只有 
  1,23  
 
  一条记录了,

 彻底晕了,

 于是上网问,上网查

 终于找到原因了

 select   A.A,B.BB   FROM   A,B   WHERE   A.A   *=   B.A   AND   B.CC   =   33  
   
  等价于
   
  select   A.A,B.BB   FROM   A   Left   Join   B   ON   A.A   =   B.A   AND   B.CC   =   33  
   
  等价于
   
  select   A.A,C.BB   FROM   A   Left   Join   (select   *   from   B   WHERE   CC   =   33)   C   ON   A.A   =   C.A


 而第二种:

 select   A.A   B.BB   FROM   A   Left   Join   b   ON   A.A   =   B.A where   B.CC   =   33  
   
   等价于 
   
  select   C.AA,C.BB   from   (select   A.A,B.BB,B.CC   FROM   A   Left   Join   b   ON   A.A   =   B.A)   C   where      

C.CC=33


 终于明白了

 如果没有别的条件(比如没有这里的B.CC   =   33),两种查询的结果是一样的了,

 但是如果有别的条件,如B.CC   =   33,那么如果用*=的写法,那么这个条件其实相当于一个join的条件而已,

 而如果用Left   Join的写法,那么这个B.CC   =   33的条件,就相当于一个查询的条件,就是说先做join,然后根据这个join以后的结果

,再根据这个B.CC   =   33 再进行筛选。
  
 
 注:以上查询在Sybase 和SQL  2000中验证通过

<think>首先,用户的问题是关于SQL中的左连接(LEFT JOIN)的语法示例。他们引用了几个内容,所以我需要回顾这些引用以理解上下文。 引用[1]提到LEFT JOINSQL连接的一种方式,根据共同列返回数据。它定义了LEFT JOIN作为左连接,但未提供具体语法。 引用[2]讨论了LEFT JOIN的示例:它返回左的所有行,即使右没有匹配的行,右列以NULL填充。它给出了一个查询示例:SELECT t1.*, t2.* FROM A t1 LEFT JOIN B t2 ON t1.bid = t2.id;。这是一个很好的语法示例。 引用[3]是关于MySQL LEFT JOIN的语法用法,强调LEFT JOIN取出左所有记录,相对于INNER JOIN的限制。 用户明确说:"我想用户想了解在数据库查询中如何编写左连接(LEFT JOIN)的SQL语句。 请问SQL 左连接 LEFT JOIN 语法示例"。所以,我的回答应该专注于提供LEFT JOIN的语法示例。 现在,系统指令要求: - 所有行内数学达式使用$...$格式(但这里没有数学达式,所以可能不适用)。 - 独立公式使用$$...$$并单独成段(同样,不适用)。 - LaTeX语法正确(在SQL代码中不需要)。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 在用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 结构回答: 1. **介绍LEFT JOIN**:简要解释LEFT JOIN是什么。 2. **语法格式**:提供通用语法。 3. **示例**:给出一个或多个示例查询。 4. **解释示例**:解释示例如何工作。 5. **生成相关问题**:在末尾添加相关问题。 引用处理:由于引用提供了信息,我需要在回答中自然地添加引用标识。例如,当提到LEFT JOIN的定义或示例时,添加[^1]或[^2]。 从引用[2]中,我可以直接使用那个示例:SELECT t1.*, t2.* FROM A t1 LEFT JOIN B t2 ON t1.bid = t2.id; 并引用[^2]。 生成相关问题:指令说"生成相关问题",所以我需要在回答末尾添加相关问题,类似于示例中的"§§相关问题§§"。 相关问题应基于主题,例如: - LEFT JOIN与其他JOIN的区别。 - 实际应用场景。 - 常见错误或优化。 最终回答结构: - 开头:解释LEFT JOIN。 - 主体:提供语法和示例。 - 结尾:添加相关问题。</think>### SQL 左连接 (LEFT JOIN) 语法示例 在SQL中,左连接(LEFT JOIN)是一种常用的连接操作,它返回左第一个)的所有行,以及右(第二个)中匹配的行。如果右没有匹配的行,则右的列以NULL值填充。这使得LEFT JOIN特别适合需要保留左所有数据的场景,例如分析主记录时可能关联的辅助数据[^1]。下面我将逐步解释语法并提供具体示例,帮助您掌握LEFT JOIN的使用。 #### 1. LEFT JOIN 的基本语法 LEFT JOIN的标准语法格式如下: ```sql SELECT 列名 FROM 左名 LEFT JOIN名 ON 左名.共同列 = 右名.共同列; ``` - **SELECT 列名**:指定要查询的列,可以是特定列名(如`column1`)或通配符(如`*`示所有列)。 - **FROM 左名**:指定左的名称(通常是主)。 - **LEFT JOIN名**:指定右的名称(通常是关联)。 - **ON 条件**:定义连接条件,基于两个之间的共同列(如主键和外键)进行匹配。如果条件不满足,右列返回NULL[^2]。 #### 2. LEFT JOIN 示例 假设我们有两个:`Customers`(客户)和 `Orders`(订单)。其中: - `Customers` 包含客户信息,列如 `CustomerID`(主键)、`CustomerName`。 - `Orders` 包含订单信息,列如 `OrderID`、`CustomerID`(外键)、`OrderDate`。 我们的目标是查询所有客户及其订单(如果有的话),即使某些客户没有订单也要显示。 **示例查询:** ```sql SELECT Customers.CustomerName, Orders.OrderID, Orders.OrderDate FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID; ``` **解释:** - 这个查询从 `Customers` (左)开始。 - 使用 `LEFT JOIN` 连接 `Orders` (右),条件是 `Customers.CustomerID = Orders.CustomerID`。 - 结果会包括所有客户的行: - 如果客户有订单,显示订单信息(如 `OrderID` 和 `OrderDate`)。 - 如果客户没有订单(即右无匹配行),`OrderID` 和 `OrderDate` 列显示为 NULL[^2]。 - 例如: - 客户 "Alice" 有订单,则输出类似:`Alice | 1001 | 2023-10-01`。 - 客户 "Bob" 无订单,则输出类似:`Bob | NULL | NULL`。 #### 3. 实际应用场景和注意事项 - **应用场景**:LEFT JOIN常用于报生成、数据分析等场景,例如: - 查询所有用户及其购买记录,即使未购买的用户也要统计。 - 在电商系统中,列出所有产品及其销售详情(包括未售出的产品)。 - **注意事项**: - 确保连接条件正确(如 `ON` 子句),避免错误匹配导致数据冗余。 - 如果只想过滤结果(如排除NULL值),可以添加 `WHERE` 子句(例如 `WHERE Orders.OrderID IS NOT NULL`),但这不是LEFT JOIN的必需部分[^3]。 - LEFT JOIN在性能上可能比INNER JOIN稍慢,因为要处理所有左行,建议在大型中优化索引[^1]。 通过这个语法示例,您可以轻松编写LEFT JOIN查询。如果您有具体数据库系统(如MySQL或PostgreSQL),语法基本一致,但细节可能略有差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值