SQL進階 | 自連接

概述

????????SQL的自連接是指在一個SQL表中,使用自身表格中的實例進行聯接并查詢的操作。自連接通常使用別名來標識一個表格,在自連接中,表格被視為兩個不同的表格,并分別用不同的別名來標識。然后,在WHERE子句中使用這些別名,將它們連接起來,以創建一種與自身關聯的視圖。

組合

????????假設這里有一張存放了商品名稱及價格的表,表里有“蘋果、橘子、香蕉”這 3 條記錄。

針對不同的需求,有不同的組合結果:

排列A(n,k)

查詢出所有的組合結果,有序集合。

select p1.name as name_1, p2.name as name_2
from products p1, products p2;

?

?組合C(n,k)

查詢出所有的組合結果,有相同元素的只查出一條。無序集合。

select p1.name as name_1, p2.name as name_2from products p1, products p2where p1.name > p2.name;

?

????????使用等號“=”以外的比較運算符,如“<、>、<>”進行的連接稱為“非等值連接”。這里將非等值連接與自連接結合使用了,因此稱為“非等值自連接”。

查找局部不一致的列

? ? ? ? 還是這張商品表,要查找出價格相同,名稱不同的組合。

?使用非等值連接實現。

 select distinct p1.name,p1.pricefrom products p1,products p2where p1.name <> p2.name and p1.price = p2.price

?

排序

????????現在,我們要按照價格從高到低的順序,對下面這張表里的商品進行排序。我們讓價格相同的商品位次也一樣,而緊接著它們的商品則有兩種排序方法,一種是跳過之后的位次,另一種是不跳過之后的位次。

使用窗口函數實現。

select name,price,rank() over(order by price desc) as rank_1,dense_rank() over(order by price desc) as rank_2
from products;

????????RANK函數返回一個唯一的值,當碰到相同數據時,排名按照記錄集中記錄的順序依次遞增。也就是說,如果有多個記錄的分數相同,那么這些記錄的排名將會一樣,并且下一個排名將會跳過這些排名相同的記錄。

????????DENSE_RANK函數也返回一個唯一的值,但當碰到相同數據時,所有相同數據的排名都是一樣的。與RANK函數不同的是,DENSE_RANK函數在下一個排名中會繼續緊隨這些排名相同的行,而不會跳過。也就是說,如果有多個記錄的分數相同,那么這些記錄的排名將會一樣,并且下一個排名將會緊隨在它們后面。

????????總的來說,RANK和DENSE_RANK都是用于排名的函數,但它們的策略略有不同。RANK函數在遇到相同數據時會產生間斷的排名,而DENSE_RANK函數則會產生連續的排名

?使用非等值自連接實現。

select p1.name,p1.price,( select count(p2.price) from products p2 where p2.price > p1.price ) + 1 as rank_1
from products p1
order by rank_1

?????????在子查詢中,統計出價格比自己高的記錄的條數并將其作為自己的位次,由于一定會存在價格最高的商品沒有比自己高的記錄,所以位次會從0開始統計,在子查詢的結果中+1能更明顯的展示出排名。

外連接和內連接

????????外連接(Outer Join)可以分為左外連接(Left Outer Join)、右外連接(Right Outer Join)和全外連接(Full Outer Join)。左外連接返回包括左表中的所有記錄和右表中連接字段相等的記錄,右外連接返回包括右表中的所有記錄和左表中連接字段相等的記錄,全外連接返回左右表中所有的記錄和左右表中連接字段相等的記錄。

????????內連接(Inner Join)是一種常見的連接方式,它只返回兩個表中連接字段相等的行。內連接使用比較運算符根據每個表共有的列的值匹配兩個表中的行。

? ? ? ? 還是上面那個例子,使用外連接來實現。

select p1.name,max(p1.price) as price,count(p2.name) + 1 as rank_1
from products p1 left join products p2 on p1.price < p2.price
group by p1.name
order by rank_1

????????通過左外連接,與價格大于自己的商品進行連接,按照商品名稱p1進行分組,統計商品名稱p2的記錄條數,最終結果和上面相同。

? ? ? ? 使用內連接實現。

select p1.name,max(p1.price) as price,count(p2.name) + 1 as rank_1
from products p1 inner join products p2 on p1.price < p2.price
group by p1.name
order by rank_1

?

? ? ? ? 通過查詢出的條件,可以發現,不存在排名為1的價格為100的橘子商品,這是因為內連接只會查找出p1.price < p2.price的記錄,找不到比橘子價格還高的商品,它就被排除掉了。

總結

  • 自連接經常和非等值連接結合起來使用。
  • 自連接和 GROUP BY 結合使用可以生成遞歸集合。
  • 將自連接看作不同表之間的連接更容易理解。
  • 應把表看作行的集合,用面向集合的方法來思考。
  • 自連接的性能開銷更大,應盡量給用于連接的列建立索引。

練習題?

1.請使用表products,求出兩列可重組合。

代碼如下:?

 select p1.name as name_1,p2.name as name_2 from products p1,products p2where p1.name <= p2.name

?

2.?這里準備了下面這樣增加了“地區”列的新表 DistrictProducts,請計算一下各個地區商品價格的位次。

代碼如下:

select d1.district,d1.name,d1.price,count(d2.name)+1 as rank_1
from districtproducts d1 left join districtproducts d2 on d1.price < d2.price and d1.district = d2.district
group by district,name,price
order by district,rank_1 

3.假設有下面這樣一張表DistrictProducts2,里邊原本就包含了“位次”列。不過,“位次”列的初始值都是 NULL。往這個列里寫入位次。

代碼如下:

update districtproducts2 p1
set ranking = (select rank_1 from(select count(p2.price) +1 rank_1from districtproducts2 p2where p1.district = p2.district and p2.price > p1.price) p3)

?

需要注意的是如果是下列代碼,會報錯。

 UPDATE DistrictProducts2 P1SET ranking = (SELECT COUNT(P2.price) + 1 FROM DistrictProducts2 P2WHERE P1.district = P2.districtAND P2.price > P1.price);

?報錯信息:

意思是不能先select出同一表中的某些值,再update這個表(在同一語句中)。?所以使用一張臨時表來解決問題。

擴展

????????使用PARTITION BY子句

????????PARTITION BY子句用于在窗口函數中對結果集進行分區,以便在每個分區中進行獨立的計算。PARTITION BY子句通常與ORDER BY子句一起使用,以便將數據按照指定的列進行排序,并將排序后的數據劃分為多個分區。

????????PARTITION BY子句可以將數據按照指定的列進行分組,并在每個分區中進行獨立的計算。它通常與窗口函數一起使用,以便在每個分區中計算聚合函數(如SUM、AVG、MAX等)的值。

UPDATE DistrictProducts2
SET ranking =(SELECT P1.rankingFROM (SELECT district , name ,RANK() OVER(PARTITION BY districtORDER BY price DESC) AS rankingFROM DistrictProducts2) P1WHERE P1.district = DistrictProducts2.districtAND P1.name = DistrictProducts2.name);

????????PARTITION BY 子句將數據按照district進行分組,并在每個分區中按照price列進行降序排序,并結合RANK函數生成排名。

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

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

相關文章

oracle異常:ORA-03297:文件包含在請求的 RESIZE 值以外使用的數據

出現這個問題&#xff0c;主要是在對表空間擴容的時候&#xff0c;擴容的大小<實際數據文件大小 1、擴容的語句 alter database datafile D:\APP\ADMINISTRATOR\ORADATA\ORCL\USER.DBF resize 2G; 2、若何確定擴容大小是否比實際文件大 根據路徑找到文件&#xff0c;查看…

二十、FreeRTOS之Tickless低功耗模式

本節需要掌握以下內容&#xff1a; 1&#xff0c;低功耗模式簡介&#xff08;了解&#xff09; 2&#xff0c; Tickless模式詳解&#xff08;熟悉&#xff09; 3&#xff0c; Tickless模式相關配置項&#xff08;掌握&#xff09; 4&#xff0c;Tickless低功耗模式實驗&…

自定義異步任務管理器和線程

import com.lancoo.common.utils.Threads; import com.lancoo.common.utils.spring.SpringUtils;import java.util.TimerTask; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit;/*** 異步任務管理器* * author lancoo*/ public c…

操作系統大會 openEuler Summit 2023即將召開,亮點不容錯過

【12月11日&#xff0c;北京】數字化、智能化浪潮正奔涌而來。操作系統作為數字基礎設施的底座&#xff0c;已經成為推動產業數字化、智能化發展的核心力量&#xff0c;為數智未來提供無限可能。12月15-16日&#xff0c;以“崛起數字時代 引領數智未來”為主題的操作系統大會 &…

〖Python網絡爬蟲實戰?〗- 極驗滑塊介紹(四)

訂閱&#xff1a;新手可以訂閱我的其他專欄。免費階段訂閱量1000 python項目實戰 Python編程基礎教程系列&#xff08;零基礎小白搬磚逆襲) 說明&#xff1a;本專欄持續更新中&#xff0c;訂閱本專欄前必讀關于專欄〖Python網絡爬蟲實戰〗轉為付費專欄的訂閱說明作者&#xff1…

【ArcGIS Pro微課1000例】0049:根據坐標快速定位(創建點位)的常見方法

文章目錄 一、轉到XY1. 閃爍位置2. 平移3. 標記位置二、定位1. 坐標定位2. 添加到圖形3. 添加至要素類三、添加XY坐標四、創建點要素一、轉到XY 舉例:經緯度坐標:113.2583286東, 23.1492340北 。 1. 閃爍位置 輸入坐標,點擊閃爍位置工具,即可在對應的位置出現一個綠色閃爍…

SQL注入漏洞利用

預計更新SQL注入概述 1.1 SQL注入攻擊概述 1.2 SQL注入漏洞分類 1.3 SQL注入攻擊的危害 SQLMap介紹 2.1 SQLMap簡介 2.2 SQLMap安裝與配置 2.3 SQLMap基本用法 SQLMap進階使用 3.1 SQLMap高級用法 3.2 SQLMap配置文件詳解 3.3 SQLMap插件的使用 SQL注入漏洞檢測 4.1 SQL注入…

shiro入門demo

搭建springboot項目&#xff0c;引入以下依賴&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--單元測試--><depe…

集的增刪操作

集是可以修改的&#xff0c;增加元素可以用add和update函數。刪除可以用pop、discard、remove等函數。 1 增加集里的元素 add函數的參數視為一個整體插入到集里&#xff0c;而update函數傳入的參數是把要傳入的元素拆分&#xff0c;做為個體傳入到集合中。 s set("hell…

.9.png的創建

1、創建.9.png 選中圖片&#xff0c;右擊&#xff0c;選擇Create 9-Patch file&#xff0c;點擊確定會生成一個xxx.9.png的圖片 2、繪制拉伸區域 在圖片的最外邊界繪制拉伸區域&#xff0c;按住鼠標左鍵不放&#xff0c;繪制完成后保存就可以使用了。繪制結果示意如下&…

phpstudy小皮(PHP集成環境)下載及使用

下載 https://www.xp.cn/download.html直接官網下載即可&#xff0c;下載完解壓是個.exe程序&#xff0c;直接點擊安裝就可以&#xff0c;它會自動在D盤目錄為D:\phpstudy_pro 使用 phpMyAdmin是集成的數據庫可視化&#xff0c;這里需要下載一下&#xff0c;在軟件管理-》網站程…

OPPO怎么錄屏?教程來了,讓你成為錄屏達人

“有人知道OPPO怎么錄屏嗎&#xff0c;前陣子剛買的OPPO手機&#xff0c;用起來感覺挺流暢的&#xff0c;功能也很齊全&#xff0c;最近因為工作原因&#xff0c;需要用到錄屏功能&#xff0c;但是我不知道怎么打開&#xff0c;就想問問大伙&#xff0c;OPPO怎么錄屏呀。” 在…

Redis分片集群一步一步全過程搭建

文章目錄 Redis搭建分片集群1. 搭建的分片集群結構2.準備實例和配置&#xff08;1&#xff09;創建目錄&#xff08;2&#xff09;創建配置文件&#xff08;3&#xff09;將這個文件拷貝到每個目錄下&#xff08;4&#xff09;修改每個目錄下的redis.conf&#xff0c;將其中的6…

Yocto 還是 Buildroot,構建自定義嵌入式系統時,您會選擇哪一種?

假設您正在采用集成平板開發新一代大型智能微波爐。這個創意不錯吧&#xff01;現在&#xff0c;您需要構建自定義操作系統&#xff0c;在保證不會燒焦食物&#xff08;更不要燒毀房屋哦&#xff09;的前提下&#xff0c;輔助管理各項事務。除此之外&#xff0c;您還需要創建一…

px? pt? dp? em?rem?vw?vh?ch?ex?這些單位你了解嗎?

目錄 前言 一、常見單位 1、px單位 2、dp單位 3、pt單位 4、百分比% 5、em單位 6、rem單位 7、vw和vh單位 8、ch、ex單位 二、如何換算 1、 pt和px換算 2、px和dp換算 3、em和px換算 4、rem和px換算 三、總結 前言 前端開發在日常設計中除了最常用的 px 以外&…

第二十八章 控制到 XML 模式的映射 - 流類到 XML 類型的映射

文章目錄 第二十八章 控制到 XML 模式的映射 - 流類到 XML 類型的映射將集合屬性映射到 XML 模式 第二十八章 控制到 XML 模式的映射 - 流類到 XML 類型的映射 如果類或屬性基于流&#xff0c;則它將投影為 XML 類型&#xff0c;如下表所示&#xff1a; IRIS 流的 XML 類型 …

使用BeautifulSoup 4和Pillow合并網頁圖片到一個PDF:一種高效的方式來處理網頁圖像

背景 ? 網頁上的培訓材料&#xff0c;內容全是PPT頁面圖片。直接通過瀏覽器打印&#xff0c;會存在只打印第一頁&#xff0c;并且把瀏覽器上無效信息也打印出來情況。但目標是希望將頁面圖片全部打印為pdf形式。 實現方案 利用網頁“另存為”&#xff0c;將頁面內所有圖片資…

官宣!「灣區之光群星演唱會」拉開2024新年音樂華麗序幕!

萬眾期待&#xff0c;群星薈萃&#xff01;青春寶安時尚灣區——灣區之光群星演唱會即將在2024年1月5日閃耀亮相深圳寶安。 華語歌壇巨星天后齊聚一堂&#xff0c;攜手多位實力唱將&#xff0c;共同呈現一場無與倫比的演唱會盛宴&#xff01;在深情而又充滿力量的歌聲之中&…

Linux修復磁盤壞道,重新掛載硬盤

修復磁盤 掛載報錯&#xff1a; [rootlocalhost ~]$ mount /dev/sdb /mnt/mydevmount: /dev/sdb is write-protected, mounting read-only mount: wrong fs type, bad option, bad superblock on /dev/sdb,missing codepage or helper program, or other errorIn some cases …

15、lambda表達式、右值引用、移動語義

前言 返回值后置 auto 函數名 (形參表) ->decltype(表達式) lambda表達式 lambda表達式的名稱是一個表達式 (外觀類似函數)&#xff0c;但本質絕非如此 語法規則 [捕獲表] (參數表) 選項 -> 返回類型 { 函數體; }lambda表達式的本質 lambda表達式本質其實是一個類…