<table id="km2im"></table>
  • <bdo id="km2im"><center id="km2im"></center></bdo>
    • 自動秒收錄
    • 軟件:1973
    • 資訊:56262|
    • 收錄網站:185720|

    IT精英團

    SQL中左連接左表合并去重實用技巧

    SQL中左連接左表合并去重實用技巧

    瀏覽次數:
    評論次數:
    編輯: 陽煦
    信息來源: ITPUB
    更新日期: 2022-05-24 21:24:35
    摘要

    zyc88.blog.csdn.net/article/details/83002882建表:CREATETABLE`table1`(`id`int(11)NOTNULLAUTO_INCREMENT,

    • 正文開始
    • 相關閱讀
    • 推薦作品

    zyc88.blog.csdn.net/article/details/83002882

    建表:

    CREATETABLE`table1 `(

    ` id ` int(11)NOTNULLAUTO _ INCREMENT,

    ` name`varchar(60)DEFAULTNULL,

    ` age`varchar(200)默認值空,

    ` sponsor _ id ` varchar(20)DEFAULTNULLCOMMENT '業務發起人,

    ` GMT _ create _ user ` int(11)NOTNULLCOMMENT '創建人id ',

    ` GMT _ create ` datetimenotnulldefaultcurrent _ TIMESTAMPCOMMENT '創建時間,

    ` GMT _ modified ` datetimedefaultnullcomment '修改時間,

    ` GMT _ modified _ user ` int(11)DEFAULTNULLCOMMENT '修改人id ',

    主鍵(` id `)

    )ENGINE=innod auto _ INCREMENT=12 default charset=ut F8 MB 4 comment='測試表1';

    CREATETABLE`table2 `(

    ` kid ` int(11)NOTNULLAUTO _ INCREMENT,

    ` name`varchar(60)DEFAULTNULL,

    ` sponsor _ id ` varchar(20)DEFAULTNULLCOMMENT '業務發起人,

    ` type`int(11)NOTNULLCOMMENT '創建人id ',

    ` GMT _ create ` datetimenotnulldefaultcurrent _ TIMESTAMPCOMMENT '創建時間,

    ` GMT _ modified ` datetimedefaultnullcomment '修改時間,

    ` GMT _ modified _ user ` int(11)DEFAULTNULLCOMMENT '修改人id ',

    主鍵(`小鬼`)

    )ENGINE=innod auto _ INCREMENT=12 default charset=ut F8 MB 4 comment='測試表2';

    插入數據:

    插入到`表1`(`id ',` n

    ame`, `age`, `sponsor_id`, `gmt_create_user`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (1, 't1', '11', '10', 1, '2018-10-10 20:34:03', NULL, NULL);
    INSERT INTO `table1`(`id`, `name`, `age`, `sponsor_id`, `gmt_create_user`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (2, 't2', '12', '10', 2, '2018-10-10 20:34:03', NULL, NULL);
    INSERT INTO `table1`(`id`, `name`, `age`, `sponsor_id`, `gmt_create_user`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (3, 't3', '13', '10', 3, '2018-10-10 20:34:03', NULL, NULL);
    INSERT INTO `table1`(`id`, `name`, `age`, `sponsor_id`, `gmt_create_user`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (4, 't4', '14', '20', 4, '2018-10-10 20:34:03', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (1, 't1', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (2, 't2', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (3, 't3', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (4, 't4', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (5, 't5', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (6, 't6', '10', 1, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (7, 't7', '10', 2, '2018-10-10 20:38:10', NULL, NULL);
    INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (8, 't1', '11', 1, '2018-10-10 20:38:10', NULL, NULL);

    查詢異常:

    SELECT
     a.*,
     b.type 
    FROM
     table1 a
     LEFT JOIN table2 b ON a.sponsor_id = b.sponsor_id 
    WHERE
     b.type = 1 
     AND a.sponsor_id = 10;

    簡單說明問題出現的原因:

    MySQL left join 語句格式為:A LEFT JOIN B ON 條件表達式

    left join 是以A表為基礎,A表即左表,B表即右表。

    左表(A)的記錄會全部顯示,而右表(B)只會顯示符合條件表達式的記錄,如果在右表(B)中沒有符合條件的記錄,則記錄不足的地方為NULL。

    使用left join, A表與B表所顯示的記錄數為 1:1 或 1:0,A表的所有記錄都會顯示,B表只顯示符合條件的記錄。

    但如果B表符合條件的記錄數大于1條,就會出現1:n的情況,這樣left join后的結果,記錄數會多于A表的記錄數。

    所以解決辦法 都是從一個出發點出發,使A表與B表所顯示的記錄數為 1:1對應關系。

    解決方法:

    使用非唯一標識的字段做關聯

    1 DISTINCT

    select DISTINCT(id) from a left join b on a.id=b.aid 

    DISTINCT查詢結果是 第一個表唯一的數據 重復的結果沒顯示出來

    SELECT
     DISTINCT(a.id), a.*,
     b.type 
    FROM
     table1 a
     LEFT JOIN table2 b ON a.sponsor_id = b.sponsor_id 
    WHERE
     b.type = 1 
     AND a.sponsor_id = 10;


    SELECT
     DISTINCT a.*,
     b.type 
    FROM
     table1 a
     LEFT JOIN table2 b ON a.sponsor_id = b.sponsor_id 
    WHERE
     b.type = 1 
     AND a.sponsor_id = 10;

    2 GROUP BY

    select * from a left join(select id from b group by id) as b on a.id=b.aid

    拿出b表的一條數據關聯 使A表與B表所顯示的記錄數為 1:1對應關系。

    SELECT 
     a.*,
     b.type 
    FROM
     table1 a
     LEFT JOIN ( SELECT * FROM table2 GROUP BY sponsor_id ) AS b ON a.sponsor_id = b.sponsor_id 
    WHERE
     b.type = 1 
     AND a.sponsor_id = 10;

    3 max取唯一

    select * from a left join (select max(id) from table group by id) as b on a.id=b.aid 

    拿出b表的最后一條數據關聯

    SELECT
     a.*,
     b.type 
    FROM
     table1 a
     LEFT JOIN ( SELECT MAX( kid ), type, sponsor_id FROM table2 GROUP BY sponsor_id ) AS b ON a.sponsor_id = b.sponsor_id 
    WHERE
     b.type = 1 
     AND a.sponsor_id = 10;

    4 IN巧用

    SELECT
     a.* 
    FROM
     table1 a 
    WHERE
     a.sponsor_id IN ( SELECT sponsor_id FROM table2 WHERE type = 1 AND sponsor_id = 10 );


    SELECT
     a.*,
     1 
    FROM
     table1 a 
    WHERE
     a.sponsor_id IN ( SELECT sponsor_id FROM table2 WHERE type = 1 AND sponsor_id = 10 );

    相信對于熟悉SQL的人來說,LEFT JOIN非常簡單,采用的時候也很多,但是有個問題還是需要注意一下。假如一個主表M有多個從表的話A B C …..的話,并且每個表都有篩選條件,那么把篩選條件放到哪里,就得注意嘍。

    (搜索公眾號SQL數據庫開發,回復“SQL”,送你一份SQL學習寶典)

    比如有個主表M,卡號是主鍵。

    有個從表A,客戶號、聯系方式是聯合主鍵,其中聯系方式,1-座機,2-手機號碼

    如果想要查詢所有卡號對應的手機號碼兩個字段,很簡單,SQL語句如下:

    SELECT A.卡號,B.手機號碼
    FROM A
    LEFT JOIN B
      ON A.客戶號=B.客戶號
    WHERE B.聯系方式='2'

    相信很多人這樣寫,估計實際工作中也會看到這樣的語句,并不是說這么寫一定會錯誤,實際SQL表達的思想一定是要符合業務邏輯的。

    前面已經說清楚,所有卡號對應的手機號碼。所有卡號,所以首先肯定以A表作為主表,并且左關聯B表,這樣A表所有的卡號一定會顯示出來,但是如果B表的篩選條件放到最外層,這樣就相當于將A表關聯B表又做了一遍篩選,結果就是

    就會篩選出來這么一條數據,丟失了A表中其他的卡號。

    實際工作中表結構肯定沒這么簡單,關聯的表也會很多,當有很多條件時,最好這么寫

    SELECT A.卡號,B.手機號碼
    FROM A
    LEFT JOIN (
        SELECT * FROM B
        B.聯系方式='2'
        )B
      ON A.客戶號=B.客戶號

    這么寫的話,A表中的數據肯定會完全保留,又能與B表的匹配,不會丟失數據。

    PS:

    • 表結構
    • Left Join
    • Right Join
    • Inner Join
    • 表的關聯修改和刪除
    • 笛卡爾積

    1、表結構

    表A

    2、Left Join

    示例:2.1

    Select * From A left join B on A.aid = B.bid;

    left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為準的。換句話說,左表A的記錄將會全部表示出來,而右表B只會顯示符合搜索條件的記錄(例子中為: A.aid = B.bid),B表記錄不足的地方均為NULL.

    • A表所有記錄都會顯示,A表中沒有被匹配的行(如aid=5、6的行)相應內容則為NULL。
    • 返回的記錄數一定大于A表的記錄數,如A表中aid=7行被B表匹配了3次(因為B表有三行bid=7)。

    注意:在Access中A.aid、B.bid不能縮寫成aid、bid,否則會提示“不支持鏈接表達式”,這一點不同于Where查詢。

    3、Right Join

    示例:3.1

    Select * From A right join B on A.aid = B.bid;

    仔細觀察一下,就會發現,和left join的結果剛好相反,這次是以右表(B)為基礎的,A表不足的地方用NULL填充。

    4、Inner Join

    示例:4.1

    Select * From A inner join B on A.aid = B.bid;

    這里只顯示出了 A.aid = B.bid的記錄.這說明inner join并不以誰為基礎,它只顯示符合條件的記錄。

    inner join 等同于Where查詢如:

    Select * From A, B Where A.aid = B.bid

    5、表的關聯修改和刪除

    5.1修改

    示例:5.1.1

    update A left join B on A.aid = B.bid
    set A.aname = B.bname

    上述SQL實際操作的表為"Select * From A left join B on A.aid = B.bid",因此Access會提示更新13條記錄(Select查詢出的記錄就是13條)。對比“示例:2.1”返回的結果,分析update后的A表:

    • aid=5、6的記錄,被更新為NULL
    • aid=7的記錄,被更新了3次,依次是“b1997-1”、“b1997-2”、“b1997-3”,因此其結果為最后一次更新“b1997-3”

    對于上述SQL同樣可以將“A.aname = B.bname”改成“B.bname = A.aname”,執行后B表將會被修改,但是執行后B表會增加三行“0, a2005-1;0, a2005-2;0, a2006”,這也不難理解,因為Left Join執行后,B表會出現三行空值。

    示例:5.1.2

    Where條件查詢在上面的SQL中同樣可以使用,其作用的表也是Select查詢出的關聯表。如下SQL

    update A left join B on A.aid = B.bid
    set A.aname = B.bname
    where A.aid <> 5

    執行后A表的結果:

    對比第一次update可以發現,aid=5的并沒有被更新。

    這里只講述left join,因為right join 和 inner join的處理過程等同于left join。另外Access中update語句中不能含有From關鍵字,這一點不同于其他數據庫。

    5.2刪除

    在Access中是不可以通過Left Join、Right Join、Inner Join來刪除某張表的記錄

    示例:5.2.2

    Delete From A inner join B on A.aid = B.bid
    where B.bname = "b1991"

    上述SQL的本意是刪除A表中aid=1的記錄,但執行后表A和表B均未發生任何變化。若想實現此目的,下述SQL可以實現

    Delete From A
    Where A.aid In (Select bid From B Where B.bname="b1991")

    6、笛卡爾積

    如果A表有20條記錄,B表有30條記錄,則二者關聯后的笛卡爾積工20*30=600條記實錄。也就是說A表中的每條記錄都會于B表的所有記錄關聯一次,三種關聯方式實際上就是對“笛卡爾積”的處理方式不同。



    運維入坑必看:Kubernetes平臺架構解讀
    ? 上一篇 2022-05-24
    • 運維入坑必看:Kubernetes平臺架構解讀
      0閱讀 0條評論 個贊
      Kubernetes是一個開源容器編排平臺,管理大規模分布式容器化軟件應用,是云計算發展演進的一次徹底革命性的突破。Kubernetes是谷歌的第三代容器管理系統,是Borg獨特的控制器和Omega靈……
    • 記得保命!捕捉Linux下的所有高危命令!
      0閱讀 0條評論 個贊
      1、rm-rf命令該命令可能導致不可恢復的系統崩壞。>rm-rf/#強制刪除根目錄下所有東西。>rm-rf*#強制刪除當前目錄的所有文件。>rm-rf.#強制刪除當前……
    • Kubernetes 4000節點運維經驗分享
      0閱讀 0條評論 個贊
      1摘要在PayPal,我們最近開始試水Kubernetes。我們大部分的工作負載都運行在ApacheMesos上,而作為遷移的一部分,我們需要從性能方面了解下運行Kubernetes集群……
    • 干貨:10個聚類算法的完整Python操作實例
      0閱讀 0條評論 個贊
      來源:海豚數據科學實驗室本文約7000字,建議閱讀14分鐘本文將介紹一篇關于聚類的文章,10種聚類介紹和Python代碼。聚類或聚類分析是無監督學習問題。它通常被用作數據分析技術,用于發現數據中的有趣……
    • 為什么NodeJS是構建微服務的最佳選擇?
      4閱讀 0條評論 個贊
      作者|RonFybish譯者|Sambodhi策劃|閆園園什么是微服務微服務是一種應用架構,它將每個應用功能都放在自己的服務中,與其他服務隔離。這些服務是松散耦合的,可獨立部署。這種架構……
    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    • 系統數據治理的思考與實踐
      2閱讀 0條評論 個贊
      美團住宿數據治理團隊從事數據治理工作多年,從最初的被動、單點治理,發展到后來的主動、專項治理,再發展到現在的體系化、自動化治理。一路走來,他們不斷進行積累和沉淀,也在持續思考與實踐。目前該團隊取得了一……
    • 2022年大數據五大發展趨勢
      7閱讀 0條評論 個贊
      2021年,我們看到圍繞現代數據棧的興起出現了相當大的加速效應。我們現在有一個海嘯般的通訊、影響者、投資者、專門的網站、會議和活動來宣揚它。圍繞現代數據棧的概念(盡管仍處于早期階段)與云中數據工具的爆……
    • 7 種提升Spring Boot吞吐量神技!
      0閱讀 0條評論 個贊
      一、異步執行實現方式二種:1.使用異步注解@aysnc、啟動類:添加@EnableAsync注解2.JDK8本身有一個非常好用的Future類——CompletableFuture@AllArg……
    • Linux預定任務調度(crontab) 好實用!
      0閱讀 0條評論 個贊
      概述crontab命令用于設置周期性被執行的指令。該命令從標準輸入設備讀取指令,并將其存放于“crontab”文件中,以供之后讀取和執行??梢允褂胏rontab定時處理離線任務,比如每天凌晨2點更新數……
    • 前端面試必須解決網絡中的跨域問題
      7閱讀 0條評論 個贊
      什么是跨域瀏覽器有一個重要的安全策略,稱之為「同源策略」其中,源=協議+主機+端口源=協議+主機+端口源=協議+主機+端口,兩個源相同,稱之為同源,兩個源不同,稱之為跨源或跨域比如:源1源2是否同……
    • 在Linux中檢查磁盤空間的12個有用的df命令
      1閱讀 0條評論 個贊
      1.檢查文件系統磁盤空間使用情況這df命令顯示文件系統上的設備名稱、總塊數、總磁盤空間、已用磁盤空間、可用磁盤空間和掛載點信息。[root@local~]#dfFilesystem1K-bloc……
    • 不容錯過的20個ES6技巧
      5閱讀 0條評論 個贊
      前言大家好,我是xieyezi,好久不見,我又重新回歸掘金啦,這次為大家整理了20個使用頻率很高的ES6代碼塊,希望大家喜歡……
    • 數據倉庫實踐:總線矩陣體系結構的設計
      1閱讀 0條評論 個贊
      以下文章來源于公眾號-云祁的數據江湖,作者云祁如何設計一套切實可行的數據倉庫呢?我們要明白,對于數據倉庫的設計是不能完全依賴于業務的需求,但往往又必須要服務于業務的價值。因此,在構建數據倉庫前,我們……
    • 詳細解釋Linux中的diff命令和例子
      1閱讀 0條評論 個贊
      文件比較在Linux中起著重要的作用,特別是對于程序員和Linux系統管理員。例如,如果您想找到兩個源代碼文件之間的差異來開發補丁,那么您需要一個文件比較工具來簡化這個過程。Linux中有幾……
    • Java“年度加密漏洞”修復 網友:更多堅持Java 8的理由
      9閱讀 0條評論 個贊
      文|Travis出品|OSC開源社區(ID:oschina2013)甲骨文于昨日推送了安全更新修復了一個漏洞,該漏洞允許攻擊者偽造某些種類的SSL證書和握手、雙因素認證信息,以及由一系列廣……
    • 3種方式!轉到錯誤處理最佳實踐
      1閱讀 0條評論 個贊
      以下文章來源于公眾號-云加社區,作者李森林導語|錯誤處理一直以一是編程必需要面對的問題,錯誤處理如果做的好的話,代碼的穩定性會很好。不同的語言有不同的出現處理的方式。Go語言也一樣,在本篇文章中,我們……
    • 優雅地處理重復請求(并發請求)
      1閱讀 0條評論 個贊
      利用唯一請求編號去重業務參數去重計算請求參數的摘要作為參數標識繼續優化,考慮剔除部分時間因子請求去重工具類,Java實現總結對于一些用戶請求,在某些情況下是可能重復發送的,如果是查詢類操作并無大礙,但……
    • 談談復雜項目代碼的應用分層
      1閱讀 0條評論 個贊
      —1—背景說起應用分層,大部分人都會認為這個不是很簡單嘛就controller,service,mapper三層??雌饋砗唵?,很多人其實并沒有把他們職責劃分開,在很多代碼中,controller做……
    • 臉書數據庫項目負責人:我從做基礎設施中學到的42件事
      2閱讀 0條評論 個贊
      最近讀到了分布式系統研究者MaheshBalakrishnan的一篇博客《42thingsIlearnedfrombuildingaproductiondatabase》。同樣做……
    • 記得保命!捕捉Linux下的所有高危命令!
      0閱讀 0條評論 個贊
      1、rm-rf命令該命令可能導致不可恢復的系統崩壞。>rm-rf/#強制刪除根目錄下所有東西。>rm-rf*#強制刪除當前目錄的所有文件。>rm-rf.#強制刪除當前……
    • 如何在Linux下擴展XFS根分區
      2閱讀 0條評論 個贊
      在某些情況下,/分區在Linux中磁盤空間不足。即使壓縮和刪除舊的日志文件也無濟于事,因此在這種情況下,我們別無選擇,只能擴展/文件系統。在本文中,我們將演示如何在Linux系統中擴展不……
    • 關于數據中心最強科普 一個就給你完整了解!
      1閱讀 0條評論 個贊
      數據中心,英文縮寫叫IDC,也就是InternetDataCenter(互聯網數據中心)。之所以不太直接稱之為“DC”,主要是為了避免和直流電(DirectCurrent)混淆。而且,現在的數……
    • MySQL 5.7 和 8.0 幾處細節上的差異
      9閱讀 0條評論 個贊
      MySQL8.0相對于MySQL5.7,有很多新特性,比如:快速加列、原子DDL、不可見索引、額外端口、角色管理等。這一節內容,就不講這些新特性了,只來聊聊最近在工作學習過程中遇到的幾處細節……
    • Kubernetes 4000節點運維經驗分享
      0閱讀 0條評論 個贊
      1摘要在PayPal,我們最近開始試水Kubernetes。我們大部分的工作負載都運行在ApacheMesos上,而作為遷移的一部分,我們需要從性能方面了解下運行Kubernetes集群……
    • SQL中左連接左表合并去重實用技巧
      0閱讀 0條評論 個贊
      zyc88.blog.csdn.net/article/details/83002882建表:CREATETABLE`table1`(`id`int(11)NOTNULLAUTO_INCREMENT,……
    最近發布資訊
    更多
    国产H视频在线播放,国产毛多水多的老女人,国产成人午夜福利电影在线播放
    <table id="km2im"></table>
  • <bdo id="km2im"><center id="km2im"></center></bdo>