最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

注意:下面的案例特別重要!請(qǐng)重視!SQL有點(diǎn)長(zhǎng),但確實(shí)是干貨!

結(jié)論

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

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

案例

有一張分?jǐn)?shù)表,表字段有日期、姓名、語文得分和數(shù)學(xué)得分等,請(qǐng)統(tǒng)計(jì)每個(gè)日期中,語文最高得分的姓名和分?jǐn)?shù),數(shù)學(xué)最低得分的姓名和分?jǐn)?shù)。

思路:過濾出所有日期 left join 篩選語文 on … left join 數(shù)學(xué)得分 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

正確結(jié)果:

錯(cuò)誤的SQL:

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

錯(cuò)誤結(jié)果:

錯(cuò)誤原因:

  • 查詢語文最高成績(jī)時(shí),沒有查到2019-12-01的數(shù)據(jù)
  • 查詢數(shù)學(xué)最低成績(jī)時(shí),使用on與語文最高成績(jī)關(guān)聯(lián),因?yàn)闆]有查到語文最高成績(jī)的日期,所以兩個(gè)表關(guān)聯(lián)時(shí),數(shù)學(xué)最低成績(jī)即使有數(shù)據(jù),也會(huì)因?yàn)檎Z文最高成績(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后查詢碰到的大坑

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

那么對(duì)于初學(xué)者,往往會(huì)犯一個(gè)錯(cuò)誤,就是 想當(dāng)然 地 認(rèn)為, ON 后面的條件是逐一執(zhí)行的,因?yàn)闆]有了解清楚 ON 后面接條件的規(guī)則。

是個(gè)什么樣的場(chǎng)景? 

看實(shí)例講解:

userinfo 表 :

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

jobinfo表 :

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

業(yè)務(wù)需求:

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

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

使用 WHERE

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

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

查詢出來的結(jié)果如下:

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

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

初學(xué)者(罪過)寫的SQL :

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

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

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

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

原因 

因?yàn)槿绻苯影殃P(guān)聯(lián)表的篩選條件拼接在 ON 后, 執(zhí)行的順序其實(shí)是:

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

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

然后再進(jìn)行連接查詢,也就是 

整個(gè)sql語句其實(shí)變成了:

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

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

那么我們?cè)谑褂?nbsp;LEFT JOIN ...... ON  ...... 拼接篩選條件時(shí),我們應(yīng)該怎么做?

配合 WHERE 使用:

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

結(jié)果:

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

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

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

所以這是我們想要得到的結(jié)果。

這是一個(gè)使用 LEFT JOIN 的 ON  初學(xué)者很容易犯的錯(cuò)誤,大家稍微注意點(diǎn)。

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

相關(guān)文章

  • MySQL 時(shí)間類型的選擇

    MySQL 時(shí)間類型的選擇

    MySQL 有多種類型存儲(chǔ)日期和時(shí)間,例如 YEAR 和 DATE。MySQL 的時(shí)間類型存儲(chǔ)的精確度能到秒(MariaDB 可以到毫秒級(jí))。但是,也可以通過時(shí)間計(jì)算達(dá)到毫秒級(jí)。時(shí)間類型的選擇沒有最佳,而是取決于業(yè)務(wù)需要如何處理時(shí)間的存儲(chǔ)。
    2021-06-06
  • MySQL新手入門進(jìn)階語句匯總

    MySQL新手入門進(jìn)階語句匯總

    這篇文章主要給大家介紹了關(guān)于MySQL新手入門進(jìn)階語句的相關(guān)資料,總結(jié)分析了MySQL數(shù)據(jù)庫常用的查詢、條件查詢、排序、連接查詢、子查詢等相關(guān)操作技巧,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • MySQL的Replace into 與Insert into on duplicate key update真正的不同之處

    MySQL的Replace into 與Insert into on duplicate key update真正的不同

    今天聽同事介紹oracle到mysql的數(shù)據(jù)migration,他用了Insert into ..... on duplicate key update ...,我當(dāng)時(shí)就想怎么不用Replace呢,于是回來就仔細(xì)查了下,它們果然還是有區(qū)別的
    2014-02-02
  • 基于mysql體系結(jié)構(gòu)的深入解析

    基于mysql體系結(jié)構(gòu)的深入解析

    本篇文章是對(duì)mysql體系結(jié)構(gòu)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • MySQL的id關(guān)聯(lián)和索引使用的實(shí)際優(yōu)化案例

    MySQL的id關(guān)聯(lián)和索引使用的實(shí)際優(yōu)化案例

    這篇文章主要介紹了MySQL的id關(guān)聯(lián)實(shí)際優(yōu)化案例,關(guān)聯(lián)和索引一直是MySQL常見的可優(yōu)化大塊兒,需要的朋友可以參考下
    2015-05-05
  • 基于ubuntu中使用mysql實(shí)現(xiàn)opensips用戶認(rèn)證的解決方法

    基于ubuntu中使用mysql實(shí)現(xiàn)opensips用戶認(rèn)證的解決方法

    本篇文章小編為大家介紹,基于ubuntu中使用mysql實(shí)現(xiàn)opensips用戶認(rèn)證的解決方法。需要的朋友參考下
    2013-04-04
  • MySQL中執(zhí)行計(jì)劃explain命令示例詳解

    MySQL中執(zhí)行計(jì)劃explain命令示例詳解

    這篇文章主要給大家介紹了關(guān)于MySQL中執(zhí)行計(jì)劃explain命令的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用explain命令具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面說來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • 使用python連接mysql數(shù)據(jù)庫之pymysql模塊的使用

    使用python連接mysql數(shù)據(jù)庫之pymysql模塊的使用

    這篇文章主要介紹了使用python連接mysql數(shù)據(jù)庫之pymysql模塊的使用,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • MySQL行級(jí)鎖、表級(jí)鎖、頁級(jí)鎖詳細(xì)介紹

    MySQL行級(jí)鎖、表級(jí)鎖、頁級(jí)鎖詳細(xì)介紹

    這篇文章主要介紹了MySQL行級(jí)鎖、表級(jí)鎖、頁級(jí)鎖詳細(xì)介紹,同時(shí)列舉了一些實(shí)例說明,需要的朋友可以參考下
    2014-05-05
  • mysql 8.0.11安裝配置方法圖文教程

    mysql 8.0.11安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql 8.0.11安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08

最新評(píng)論

德惠市| 大理市| 临泽县| 成安县| 泽州县| 成安县| 汝城县| 广昌县| 天津市| 淄博市| 阿图什市| 酒泉市| 邢台市| 淅川县| 丰原市| 乌拉特后旗| 凉城县| 江山市| 临朐县| 延川县| 大理市| 蓬溪县| 宁城县| 南投市| 长治市| 泾川县| 堆龙德庆县| 林州市| 保定市| 苏尼特右旗| 饶阳县| 涞水县| 聂拉木县| 南丹县| 嘉善县| 东光县| 佛山市| 建平县| 盐源县| 黎城县| 吴江市|