欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL中多個left?join?on關聯(lián)條件的順序說明

 更新時間:2022年11月16日 11:02:11   作者:p7+  
這篇文章主要介紹了MySQL中多個left?join?on關聯(lián)條件的順序說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

MySQL多個left join on關聯(lián)條件順序

注意:下面的案例特別重要!請重視!SQL有點長,但確實是干貨!

結論

如果存在多個left join on,請注意on后面的條件與哪個表關聯(lián)。這一條統(tǒng)計的SQL很重要!例如表A,B,C,A left join B on A.x = B.x left join C on A.x = C.x,B和C的都要和A建立關聯(lián),B和C之間是沒有任何數(shù)據(jù)上的關系。

但是 如果把A.x = C.x改成B.x = C.x,那么B和C的表數(shù)據(jù)先建立關聯(lián)并過濾數(shù)據(jù),再與A表數(shù)據(jù)進行關聯(lián),這樣可能會出現(xiàn)數(shù)據(jù)丟失!

案例

有一張分數(shù)表,表字段有日期、姓名、語文得分和數(shù)學得分等,請統(tǒng)計每個日期中,語文最高得分的姓名和分數(shù),數(shù)學最低得分的姓名和分數(shù)。

思路:過濾出所有日期 left join 篩選語文 on … left join 數(shù)學得分 on …

正確的SQL:

SELECT
	* 
FROM
	( SELECT report_date reportDate FROM tb_more_left_join mlj GROUP BY mlj.report_date ) mix
	LEFT JOIN (
SELECT
	mlj.report_date maxReportDate,
	GROUP_CONCAT( mlj.user_name ) maxUserNames,
	a.maxScore 
FROM
	tb_more_left_join mlj
	LEFT JOIN ( SELECT report_date, MAX( chinese_score ) maxScore FROM tb_more_left_join mlj GROUP BY mlj.report_date ORDER BY NULL ) a ON mlj.report_date = a.report_date 
WHERE
	mlj.chinese_score = a.maxScore 
GROUP BY
	mlj.report_date 
	) mx ON mix.reportDate = mx.maxReportDate
	LEFT JOIN (
SELECT
	mlj.report_date minReportDate,
	GROUP_CONCAT( mlj.user_name ) minUserNames,
	a.minScore 
FROM
	tb_more_left_join mlj
	LEFT JOIN ( SELECT report_date, MIN( math_score ) minScore FROM tb_more_left_join mlj GROUP BY mlj.report_date ORDER BY NULL ) a ON mlj.report_date = a.report_date 
WHERE
	mlj.math_score = a.minScore 
GROUP BY
	mlj.report_date 
	) mn ON mix.reportDate = mn.minReportDate

正確結果:

錯誤的SQL:

把正確SQL中最后一個on條件改為mx.maxReportDate = mn.minReportDate,注意,是把mix.reportDate改為了mx.maxReportDate。

錯誤結果:

錯誤原因:

  • 查詢語文最高成績時,沒有查到2019-12-01的數(shù)據(jù)
  • 查詢數(shù)學最低成績時,使用on與語文最高成績關聯(lián),因為沒有查到語文最高成績的日期,所以兩個表關聯(lián)時,數(shù)學最低成績即使有數(shù)據(jù),也會因為語文最高成績無數(shù)據(jù)而被忽略。

SQL數(shù)據(jù)

CREATE TABLE `tb_more_left_join`  (
  `id` int(11) NOT NULL,
  `report_date` date NULL DEFAULT NULL,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `math_score` int(255) NULL DEFAULT NULL,
  `chinese_score` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `tb_more_left_join` VALUES (1, '2019-12-01', '盲僧', 70, NULL);
INSERT INTO `tb_more_left_join` VALUES (2, '2019-12-01', '薇恩', 100, NULL);
INSERT INTO `tb_more_left_join` VALUES (3, '2019-12-02', '趙信', 30, 60);
INSERT INTO `tb_more_left_join` VALUES (4, '2019-12-02', '琴女', NULL, 100);
INSERT INTO `tb_more_left_join` VALUES (5, '2019-12-03', '蠻王', 50, 100);
INSERT INTO `tb_more_left_join` VALUES (6, '2019-12-03', '艾希', 100, 100);
INSERT INTO `tb_more_left_join` VALUES (7, '2019-12-03', '亞索', 60, 90);

使用left join的on后查詢碰到的大坑

很多時候我們在使用  LEFT JOIN   ...... ON .... 時, 除了連接兩個表的字段條件外,我們往往還需要一些等值或者范圍 等等類似的數(shù)據(jù)篩選條件。

那么對于初學者,往往會犯一個錯誤,就是 想當然 地 認為, ON 后面的條件是逐一執(zhí)行的,因為沒有了解清楚 ON 后面接條件的規(guī)則。

是個什么樣的場景? 

看實例講解:

userinfo 表 :

(找兼職的人員名單信息表)

jobinfo表 :

(兼職工作信息及職業(yè)要求表)

業(yè)務需求:

根據(jù)職業(yè)要求 給 找兼職的人員 匹配上 目前 可以做的兼職,輸出數(shù)據(jù)條。 

例如,李三是一個程序員,他迫于經(jīng)濟壓力,不得不向社會低頭,想找一些自己能做的兼職。

使用 WHERE

如果我們不用  left join ...... on ... , 僅僅使用 where,那么簡單寫下sql是:

SELECT * 
FROM userinfo AS u ,jobinfo AS j 
WHERE u.userProfession=j.professionRequire
AND j.professionRequire='程序員'

查詢出來的結果如下:

是我們需要的結果,可以看的,程序員李三能做的兼職有,送外賣或者當保安。 

使用 LEFT JOIN ...... ON  ......

初學者(罪過)寫的SQL :

想當然地把篩選條件 職業(yè)要求為 ‘ 程序員’  直接 拼接在 ON 后面

SELECT * 
FROM userinfo AS u 
LEFT JOIN   
jobinfo AS j 
ON u.userProfession=j.professionRequire
AND j.professionRequire='程序員'

這樣地拼接篩選條件其實是達不到所想要的效果的,先來看看這樣的執(zhí)行結果:

可以看到查詢出來很多我們不想要的數(shù)據(jù),為什么會這樣?

原因 

因為如果直接把關聯(lián)表的篩選條件拼接在 ON 后, 執(zhí)行的順序其實是:

將 jobinfo 表 按照篩選條件  professionRequire='程序員'  執(zhí)行后作為子查詢,再執(zhí)行 LEFT JOIN ...... ON 。

也就是第一步變成了執(zhí)行  SELECT *  FROM jobinfo AS j  WHERE  j.professionRequire='程序員'  

然后再進行連接查詢,也就是 

整個sql語句其實變成了:

SELECT * 
FROM userinfo AS u 
LEFT JOIN   
(SELECT *  FROM jobinfo  WHERE jobinfo.professionRequire='程序員') AS j 
ON 
u.userProfession=j.professionRequire

這樣查詢出來,顯然不是我們想要的結果。

那么我們在使用 LEFT JOIN ...... ON  ...... 拼接篩選條件時,我們應該怎么做?

配合 WHERE 使用:

SELECT * 
FROM userinfo AS u 
LEFT JOIN   jobinfo AS j 
ON u.userProfession=j.professionRequire
WHERE j.professionRequire='程序員'

結果:

我們把篩選條件配合where去使用, 執(zhí)行的邏輯就是:

先執(zhí)行LEFT JOIN ...... ON  ......  先將關聯(lián)兩個表之后的數(shù)據(jù)查詢出來;

再按照 professionRequire='程序員'   條件,進行數(shù)據(jù)篩選。

所以這是我們想要得到的結果。

這是一個使用 LEFT JOIN 的 ON  初學者很容易犯的錯誤,大家稍微注意點。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • MySQL批量導入Excel數(shù)據(jù)(超詳細)

    MySQL批量導入Excel數(shù)據(jù)(超詳細)

    這篇文章主要介紹了MySQL批量導入Excel數(shù)據(jù)(超詳細),文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下,希望對你的學習有所幫助
    2022-08-08
  • Mac 安裝 mysqlclient過程解析

    Mac 安裝 mysqlclient過程解析

    這篇文章主要介紹了Mac 安裝 mysqlclient過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 利用ssh tunnel鏈接mysql服務器的方法

    利用ssh tunnel鏈接mysql服務器的方法

    這篇文章主要給大家介紹了利用ssh tunnel鏈接mysql服務器的方法,文中介紹的很詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 安裝mysql-8.0.19-winx64遇到的問題:Can''t create directory ''xxxx\Database\''

    安裝mysql-8.0.19-winx64遇到的問題:Can''t create directory ''xxxx\Da

    這篇文章主要介紹了安裝mysql-8.0.19-winx64遇到的坑 ,Can't create directory 'xxxx\Database\',非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • MySQL INSERT INTO SELECT時自增Id不連續(xù)問題及解決

    MySQL INSERT INTO SELECT時自增Id不連續(xù)問題及解決

    這篇文章主要介紹了INSERT INTO SELECT時自增Id不連續(xù)問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • debian6配置mysql允許遠程連接的方法(圖)

    debian6配置mysql允許遠程連接的方法(圖)

    這篇文章主要介紹了debian6配置mysql允許遠程連接的方法,大家可以參考,最后可看圖
    2013-11-11
  • Centos7安裝 mysql5.6.29 shell腳本

    Centos7安裝 mysql5.6.29 shell腳本

    這篇文章主要為大家詳細介紹了Centos7安裝mysql5.6.29的shell腳本,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • SQL中CONVERT轉換函數(shù)的簡單使用方法

    SQL中CONVERT轉換函數(shù)的簡單使用方法

    CONVERT()函數(shù)對于簡單類型轉換,CONVERT()函數(shù)和CAST()函數(shù)的功能相同,只是語法不同,下面這篇文章主要給大家介紹了關于SQL中CONVERT轉換函數(shù)的簡單使用方法,需要的朋友可以參考下
    2024-01-01
  • Linux環(huán)境下設置MySQL表名忽略大小寫的方法小結

    Linux環(huán)境下設置MySQL表名忽略大小寫的方法小結

    在MySQL中,表名的大小寫敏感性取決于操作系統(tǒng)和MySQL的配置,在Unix/Linux系統(tǒng)上,表名通常是區(qū)分大小寫的,由于之前MySQL未設置忽略表名大小寫導致數(shù)據(jù)查詢失敗等問題,所以本文給大家介紹了Linux環(huán)境下設置MySQL表名忽略大小寫的方法,需要的朋友可以參考下
    2024-06-06
  • Mysql支持的數(shù)據(jù)類型(列類型總結)

    Mysql支持的數(shù)據(jù)類型(列類型總結)

    MySQL支持大量的列類型,它可以被分為3類:數(shù)字類型、日期和時間類型以及字符串(字符)類型。本節(jié)首先給出可用類型的一個概述,并且總結每個列類型的存儲需求,然后提供每個類中的類型性質的更詳細的描述
    2016-12-12

最新評論