zoukankan      html  css  js  c++  java
  • 内连接,左连接,右连接,全外链接

    菜鸟一枚

    最近在看别人代码的时候,总是碰到诸如join on的SQL语句,上课那会儿老师也仔细的讲过,

    单独的拿出来看的话也是很简单的,只是放在那样复杂的SQL语句中,阅读起来还是很费劲。

    正好今天不怎么忙,查查资料在总结一下。

      工作中,我们都习惯了只查询一张表中的数据,如果业务中需要去查询另外一张表中的数据时,

    我们往往习惯于遍历查询的数据然后根据外键字段去查询另外一张表,这样做没有什么问题。

    但是当我们需要关联3张表甚至4张表,或者在一些大型的项目中需要些一些非常复杂的SQL语句

    的时候我们发现,这样会使业务层的代码非常非常复杂。

      这个时候,关联表查询就会变得非常重要。

    基本定义:

      left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。

      right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。

      inner join (等值连接):只返回两个表中连接字段相等的行。

      full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。

    现在呢举个例子:

      A表          

      id   name  

      1  小王

      2  小李

      3  小刘

      B表

      id  A_id  job

      1  2    老师

      2  4    程序员

      

      select a.name,b.job from A a  inner join B b on a.id=b.A_id

      只能得到一条记录

      小李  老师

      select a.name,b.job from A a  left join B b on a.id=b.A_id

      三条记录

      小王  null

      小李  老师

      小刘  null

      select a.name,b.job from A a  right join B b on a.id=b.A_id

      两条记录

      小李  老师

      null  程序员

      select a.name,b.job from A a  full join B b on a.id=b.A_id

      四条数据

      小王  null

      小李  老师

      小刘  null

      null  程序员

      以上的具体用法就看你的业务需求了,比如查询多有人的职业,没有职业的设置为null,左连接无疑是最

    正确的,再比如查询所有职业对于的人,没有所对应的人就设置为0.右连接更为正确。

      当然在工作的我们会看到关联好几张表的情况,这时候我们会多写几个join on语句,具体是哪个连接要按

    具体的业务而定。

      

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     3 <!-- 库存映射 -->
     4 <mapper namespace="com.hebg3.mobiledealer.modules.client.store.order.dao.OrderDao">
     5 
     6     <sql id="tOrderColumns">
     7         a.id AS "id",<!-- 主键 -->
     8         a.order_no AS "orderNo",<!-- 订单编号 -->
     9         a.t_customer_id AS "customer.id",<!-- 客户编号 -->
    10         a.sys_office_id AS "companyOffice.id",<!-- 公司编号 -->
    11         a.order_date AS "orderDate",<!-- 订单日期 -->
    12         a.document_status AS "documentStatus",<!-- 订单状态 -->
    13         a.send_date AS "sendDate",<!-- 发送时间 -->
    14         a.open_id AS "openId",<!-- 微信编号 -->
    15         a.create_by AS "createBy.id",<!-- 建立人 -->
    16         a.create_date AS "createDate",<!-- 建立时间 -->
    17         a.update_by AS "updateBy.id",<!-- 更新人 -->
    18         a.update_date AS "updateDate",<!-- 更新时间 -->
    19         a.remarks AS "remarks",<!-- 备注 -->
    20         a.del_flag AS "delFlag",<!-- 删除标志 -->
    21         a.t_sales_entry_id AS "salesEntry.id",<!-- 销售单号 -->
    22         se.orderno AS "salesEntry.orderno",
    23         c.name AS "customer.name"<!-- 客户名称 -->
    24     </sql>
    25 
    26     <sql id="tOrderJoins">
    27         JOIN t_customer_relation cr ON cr.t_customer_id = a.t_customer_id<!-- 关联客户关系 -->
    28         JOIN t_customer c ON c.id=a.t_customer_id<!-- 关联客户关系 -->
    29         LEFT JoIN t_sales_entry se ON se.id=a.t_sales_entry_id<!-- 关联销售单 -->
    30     </sql>
    31 
    32 
    33     <!-- 根据条件取得 订单信息列表 -->
    34     <select id="findPageOrder" resultType="TOrder">
    35         SELECT
    36         <include refid="tOrderColumns" />
    37         FROM t_order a
    38         <include refid="tOrderJoins" />
    39         <where>
    40             a.del_flag = #{DEL_FLAG_NORMAL}
    41             <if test="userId!=null and userId!=''">
    42                 AND cr.sys_user_id=#{userId}
    43             </if>
    44             <if test="id!=null and id!=''">
    45                 AND a.id=#{id}
    46             </if>
    47             <if
    48                 test="companyOffice !=null and companyOffice.id!=null and companyOffice.id!=''">
    49                 AND cr.sys_office_id=#{companyOffice.id}
    50             </if>
    51             <if test="documentStatus!=null and documentStatus!=''">
    52                 AND a.document_status =#{documentStatus}
    53             </if>
    54             <if test="documentStatusList != null"><!-- 根据单据状态查找 -->
    55                 AND a.document_status in
    56                 <foreach item="item" index="index" collection="documentStatusList" open="(" separator="," close=")">
    57                     #{item}
    58                 </foreach>
    59                  
    60             </if>
    61             <if test="page !=null and page.groupBy != null and page.groupBy != ''">
    62                 group by ${page.groupBy}
    63             </if>
    64         </where>
    65         <choose>
    66             <when test="page !=null and page.orderBy != null and page.orderBy != ''"><!-- 根据 排序字段 排序 -->
    67                 ORDER BY ${page.orderBy}
    68             </when>
    69             <otherwise>
    70                 ORDER BY a.create_date DESC
    71             </otherwise>
    72         </choose>
    73 
    74     </select>

      上图中26到30行,便是在关联多张表的复杂查询。我在原来的博客中提到过动态查询,大家也可以借鉴一下。

      

      以上

  • 相关阅读:
    菜根谭#245
    菜根谭#244
    菜根谭#243
    菜根谭#242
    菜根谭#241
    菜根谭#240
    菜根谭#239
    菜根谭#238
    菜根谭#237
    [转载]Linux 内核list_head 学习(一)
  • 原文地址:https://www.cnblogs.com/fengchaoLove/p/5858864.html
Copyright © 2011-2022 走看看