(菜鳥一枚)
最近在看別人代碼的時候,總是碰到諸如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行,便是在關聯多張表的復雜查詢。我在原來的博客中提到過動態查詢,大家也可以借鑒一下。
以上