sql三個表join_「數據蔣堂」第 31 期:JOIN 簡化 – 維度對齊

【數據蔣堂】第 31 期:JOIN 簡化 – 維度對齊

c2ba34d2cd6836ed1be55540914320cd.png

我們先把上一期中雙子表對齊例子的 SQL 寫出來:

 SELECT Orders.id, Orders.customer, A.x, B.y FROM Orders  LEFT JOIN (SELECT id,SUM(price) x FROM OrderDetail GROUP BY id ) A ON Orders.id=A.id  LEFT JOIN (SELECT id,SUM(amount) y FROM OrderPayment GROUP BY id ) B ON Orders.id=B.id  WHERE A.x > B.y SELECT Orders.id, Orders.customer, A.x, B.y FROM Orders  LEFT JOIN (SELECT id,SUM(price) x FROM OrderDetail GROUP BY id ) A ON Orders.id=A.id  LEFT JOIN (SELECT id,SUM(amount) y FROM OrderPayment GROUP BY id ) B ON Orders.id=B.id  WHERE A.x > B.y

那么問題來了,這顯然是個有業務意義的 JOIN,它算是前面所說的哪一類呢?

這個 JOIN 涉及了表 Orders 和子查詢 A 與 B,仔細觀察會發現,子查詢帶有 GROUP BY id 的子句,顯然,其結果集將以 id 為主鍵。這樣,JOIN 涉及的三個表(子查詢也算作是個臨時表)的主鍵是相同的,它們是一對一的同維表,仍然在前述的范圍內。

但是,這個同維表 JOIN 卻不能用上一期說的寫法簡化,子查詢 A,B 都不能省略不寫。

可以簡化書寫的原因在于:我們假定事先知道數據結構中這些表之關聯關系。用技術術語的說法,就是知道數據庫的元數據(metadata)。而對于臨時產生的子查詢,顯然不可能事先定義在元數據中了,這時候就必須明確指定要 JOIN 的表(子查詢)。

不過,雖然 JOIN 的表不能省略,但關聯字段總是主鍵,已經在 GROUP BY 中寫過了,就沒有必要再寫一遍了;而且,子查詢的主鍵總是由 GROUP 產生,而 GROUP BY 的字段一定要被選出用于做外層 JOIN,也沒必要在 GROUP 和 SELECT 中各寫一次;并且這幾個子查詢涉及的子表是互相獨立的,它們之間不會再有關聯計算了,我們就可以把 GROUP 動作以及聚合式直接放到主句中,從而消除一層子查詢:

 SELECT Orders.id, Orders.customer, OrderDetail.SUM(price) x, OrderParyment.SUM(amount) y  FROM Orders LEFT JOIN OrderDetail GROUP BY id LEFT JOIN OrderPayment GROUP BY id  WHERE A.x > B.y SELECT Orders.id, Orders.customer, OrderDetail.SUM(price) x, OrderParyment.SUM(amount) y  FROM Orders LEFT JOIN OrderDetail GROUP BY id LEFT JOIN OrderPayment GROUP BY id  WHERE A.x > B.y

這里的 JOIN 和 SQL 定義的 JOIN 運算已經差別很大,完全沒有笛卡爾積的意思了。而且,也不同于 SQL 的 JOIN 運算將定義在任何兩個表之間,這里的 JOIN,OrderDetail 和 OrderPayment 以及 Orders 都是向共同的主鍵 id 靠攏,即所有表都向某一套基準維度對齊。而由于各表的維度(主鍵)不同,對齊時可能會有 GROUP BY,在引用該表字段時就會相應地出現聚合運算。OrderDetail 和 OrderPayment 甚至 Orders 之間都不直接發生關聯,在書寫運算時當然就不用關心它們之間的關系,甚至不必關心另一個表是否存在。而 SQL 那種笛卡爾積式的 JOIN 則總要找一個甚至多個表來定義關聯,一旦減少或修改表時就要同時考慮關聯表,增大理解難度。

我們稱這種 JOIN 稱為維度對齊,它并不超出我們前面說過的三種 JOIN 范圍,但確實在語法描述上會有不同,這里的 JOIN 不象 SQL 中是個動詞,卻更象個連詞。而且,和前面三種基本 JOIN 中不會或很少發生 FULL JOIN 的情況不同,維度對齊的場景下 FULL JOIN 并不是很罕見的情況。

雖然我們從主子表的例子抽象出維度對齊,但這種 JOIN 并不要求 JOIN 的表是主子表(事實上從上一篇的語法可知,主子表運算還不用寫這么麻煩),任何多個表都可以這么關聯,而且關聯字段也完全不必要是主鍵或主鍵的部分。

設有合同表,回款表和發票表:

Contract 合同表

id合同編號date簽訂日期customer客戶price合同金額……

Payment 回款表

seq回款序號date回款日期source回款來源amount金額……

Invoice 發票表

code 發票編號

date 開票日期

customer 客戶

amount 開票金額

現在想統計每一天的合同額、回款額以及發票額,就可以寫成:

 SELECT Contract.SUM(price), Payment.SUM(amount), Invoice.SUM(amount)  FROM Contract GROUP BY date FULL JOIN Payment GROUP BY date FULL JOIN Invoice GROUP BY date SELECT Contract.SUM(price), Payment.SUM(amount), Invoice.SUM(amount)  FROM Contract GROUP BY date FULL JOIN Payment GROUP BY date FULL JOIN Invoice GROUP BY date

這幾種 JOIN 情況還可能混合出現。

延用上面的合同表,再有客戶表和銷售員表

Customer 客戶表

|—|—|

|id| 客戶編號 |

|name| 客戶名稱 |

|area| 所在地區 |

|…|…|

Sales 銷售員表

id員工編號name姓名area負責地區……

其中 Contract 表中 customer 字段是指向 Customer 表的外鍵。

現在我們想統計每個地區的銷售員數量及合同額:

 SELECT Sales.COUNT(1), Contract.SUM(price)  FROM Sales GROUP BY area FULL JOIN Contract GROUP BY customer.area SELECT Sales.COUNT(1), Contract.SUM(price)  FROM Sales GROUP BY area FULL JOIN Contract GROUP BY customer.area

維度對齊可以和外鍵屬性化的寫法配合合作。

這些例子中,最終的 JOIN 都是同維表。事實上,維度對齊還有主子表對齊的情況,不過相對罕見,我們將在后續仔細講解維度概念時再涉及,上述寫法中其實還有個小漏洞,有了明確的維度定義后才能將這個漏洞補上。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396546.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396546.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396546.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

radius

radius協議使用的是UDP傳輸協議,UDP協議相對于TCP更快速,無連接的不可靠。radius協議的包格式:0 1 2 30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1-----------…

apt-get常用命令及工作原理

https://blog.csdn.net/mosquito_zm/article/details/63684608轉載于:https://www.cnblogs.com/diyunpeng/p/9772866.html

day10_控制文件

---------------------驗證互為鏡像功能---------------------窗口1cd /oracle/app/oradata/ecomrm control03.ctl 窗口2SQL> startup force;ORACLE instance started.Total System Global Area 285212672 bytesFixed Size 1218992 bytesVariable Size …

堆疊自編碼器中的微調解釋_25種深刻漫畫中的編碼解釋

堆疊自編碼器中的微調解釋by freeCodeCamp通過freeCodeCamp 25種深刻漫畫中的編碼解釋 (Coding Explained in 25 Profound Comics) We asked our open source community to share the comics they found most profoundly described coding, via our news site. Here are their…

linux和mysql重點哪個_重要的MySQL 文檔存儲知識點掃盲

MySQL 文檔存儲 可以跳過底層數據結構創建、數據規范化和其它使用傳統數據庫時需要做的工作,直接存儲數據。MySQL 可以提供 NoSQL JSON 文檔存儲Document Store 了,這樣開發者保存數據前無需 規范化normalize 數據、創建數據庫,也無需在開發之…

python端口掃描工具_Python實現的多線程端口掃描工具分享

# -*- coding: utf-8 -*-__author__ Phtih0nimport threading, socket, sys, cmd, os, Queue#掃描常用端口PortList [21, 22, 23, 25, 80, 135, 137, 139, 445, 1433, 1502, 3306, 3389, 8080, 9015]#得到一個隊列def GetQueue(list):PortQueue Queue.Queue(65535)for p in …

Linux系統啟動全過程

分為兩部分,第一部分是硬件本身需要加載的信息,之后才是加載Linux相關信息,因為有裝有雙系統的機器嘛 1.計算機加電 2.BIOS開始運行,檢測硬件:cpu、內存、硬盤等 3.BIOS讀取CMOS存儲器中的參數,選擇啟動設備…

day09_讀寫分離_Atlas小記

GRANT ALL PRIVILEGES ON *.* TO root% identified by mysql;FLUSH PRIVILEGES;主從庫上全做--------------------------------------------------------------------yum install -y gcc*rpm -ivh Atlas-2.2.1.el5.x86_64.rpm 【rpm包直接安裝】rpm -ql Atlas 【查看安裝路徑…

Free Code Camp現在有本地組

by freeCodeCamp通過freeCodeCamp Free Code Camp現在有本地組 (Free Code Camp now has Local Groups) Our open source community was born online. And our campers are adept at using the internet to communicate. Most of this communication is just short text messa…

二十四點游戲python_[求助]關于二十四點游戲python

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓24點紙牌游戲的開發24點是一種老少咸宜的游戲,它的具體玩法如下:給玩家4張牌,每張牌的面值在1~13之間,允許其中有數值相同的牌。采用加、減、乘、除四則運算,允…

python-3.6.2安裝

1、下載python-3.6.2-amd64.exe安裝包 官網下載地址:https://www.python.org/ 2、Python安裝,雙擊傻瓜式安裝(用英文路徑,不要有空格), 特別要注意勾上Add Python 3.6 to PATH(勾選后&#xff0…

Siege壓力工具

Siege官方:http://www.joedog.org/ Siege下載:http://www.joedog.org/pub/siege/siege-latest.tar.gz Siege解壓并安裝:# tar -zxvf siege-latest.tar.gz # cd siege-latest/ #./configure #make #make installSiege使用:# siege -h 查看相關…

遞歸javascript_JavaScript中的遞歸

遞歸javascriptby Kevin Ennis凱文恩尼斯(Kevin Ennis) JavaScript中的遞歸 (Recursion in JavaScript) I’m just gonna get this out of the way right up front, because people get really angry otherwise:我只是直接解決這個問題,因為否則人們會非常生氣&…

python google drive api_Python管理Google Drive文件

背景Google Drive給我們提供了很多管理和共享文件的簡便方法,而且還是免費的(當然免費賬戶有一定存儲限制)。但是,對于某些edu用戶,Google Drive存儲不僅是免費的,而且是無配額限制的。您是否想知道如何從數據科學的角度充分利用這…

Struts2學習---基本配置,action,動態方法調用,action接收參數

首先我們先來直接配置,然后再來講原理: 第一步:jar包的引入: 我們可以到struts2的官網上下載: http://struts.apache.org/download.cgi#struts2513 然后解壓將里面的app文件夾下的示例war文件解壓,將里面的…

實現對數組找最大最小數

實現對數組找最大最小數 在用js的過程中我們往往會需要找到一個數組里最大或最小的數, 但是我們不能直接用Math.max(Arr)或Math.min(Arr),因為max()里面不能填數組,只能填連續的數。 那我們該怎么辦呢? 一定…

開源免費 低代碼平臺開源_行動透明:免費代碼營現已開源

開源免費 低代碼平臺開源by freeCodeCamp通過freeCodeCamp 行動透明:免費代碼營現已開源 (Transparency in Action: Free Code Camp is Now Open Source) We’re thrilled to announce that Free Code Camp is now fully open-source. Now you can fork our code b…

vc mysql init 崩潰_故障分析 | 崩潰恢復巨慢原因分析

作者:xuty本文來源:原創投稿*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯系小編并注明來源。一、現象有個 MySQL 5.7 開發庫異常掛掉后,奔潰恢復一直處于如下位置,且持續了 2 小時左右才起來…

surfaceview結束后怎么處理_污泥壓濾機處理后的污泥怎么處置

在污泥處理處置中,污泥壓濾機處理污泥只是對污泥進行脫水,并沒有實現污泥資源化處置。再進行污泥“減量化、無害化、資源化”處理時,許多企業用污泥壓濾機對污泥脫水處理后就不知道怎么繼續處置了,從而使污泥餅無處可去&#xff0…

js數組詳解

1,什么是數組數組是值得有序集合,每個值叫做一個元素,而每個元素在數組中有一個位置,以數字表示,稱為索引。js的數組是無類型的,數組元素可以是任意類型,同一個數組中的不同元素可能是對象或數組…