手机免费看国产欧美精品_久久精品国产9久久综合_免费无码一区二区三区视频_亚洲综合精品一二三区在线

您的位置:首頁>精選聚焦>

笛卡爾積(SQL查詢中笛卡爾積的巧妙使用)

大家好,今日我們來聊聊一篇關(guān)于笛卡爾積,SQL查詢中笛卡爾積的巧妙使用的文章,希望對大家有所幫助

笛卡爾積(在SQL查詢中巧妙使用笛卡爾積)

本文用兩個(gè)小例子來學(xué)習(xí)笛卡爾積的巧妙運(yùn)用。后臺(tái)回復(fù)“笛卡爾產(chǎn)品”即可獲得本文pdf版本,方便閱讀和保存。

笛卡爾積,也稱為交叉連接,是SQL中連接兩個(gè)表的一種方式。

如果表A的數(shù)據(jù)是M行,表B的數(shù)據(jù)是N行,那么A和B做笛卡爾積,結(jié)果是m*n行。

笛卡爾乘積是這樣寫的:

Select*fromA,B或select*fromAcrossjoinB通常情況下,我們應(yīng)該避免在實(shí)際的SQL中直接使用笛卡爾積,因?yàn)檫@樣會(huì)造成“數(shù)據(jù)爆炸”,尤其是在數(shù)據(jù)量很大的時(shí)候。但有時(shí)候,巧妙利用笛卡爾積可以幫助我們快速解決實(shí)際問題。看看下面的例子。

在此之前,我們先來看看with as的用法。

使用tmpa(select * from class)select * from tmp。上面的編寫方法首先通過執(zhí)行select * from class定義(生成)一個(gè)中間表tmp,然后使用中間表tmp。通常可以用來提取固定的查詢,只檢查一次,多次使用,從而提高效率。它還可以與union all結(jié)合來構(gòu)造測試數(shù)據(jù),我們將在本文下一部分的后面的場景中看到這種用法。關(guān)于as的一些要點(diǎn)和注意事項(xiàng),請參考以下鏈接:

https://blog.csdn.net/baidu_30527569/article/details/48680745

假設(shè)有一張損益表,每過一個(gè)小時(shí),就會(huì)自動(dòng)更新前一個(gè)小時(shí)的收入數(shù)據(jù)。但是,對于沒有更新的時(shí)間,我們希望收入值為0。這樣可以更好的體現(xiàn)完整性,也便于多日數(shù)據(jù)的對比。如下圖所示:

對于收益非零的小時(shí),我們可以直接從收益表中查詢當(dāng)前小時(shí)的收益數(shù)據(jù)。收益表結(jié)構(gòu)如下(假設(shè)當(dāng)前收益數(shù)據(jù)只更新到16點(diǎn)):

查詢SQL是:

DT,HOUR,income fromt _ H _ income whereday=' 2020-04-19 '顯然,得到的結(jié)果不會(huì)包括17點(diǎn)以后的時(shí)間。我們可以使用笛卡爾積來構(gòu)造一個(gè)小時(shí)序列,如下面的代碼所示:

with t _ houras(select ' 00 ' asdhourunionallselect ' 01 ' asdhourunionallselect ' 02 ' asdhourunionallselect ' 03 ' asdhourunionallselect ' 04 ' asdhourunionallselect ' 05 ' ASD hourinoniallselect ' 07 ' asdhourunionallselect ' 08 ' asdhourunionallselect ' 09 ' asdhourunionallselect ' 10 ' asdhourunionallselect ' 11 ' asdh ourunionallall

將上面的結(jié)果與左邊的原始數(shù)據(jù)相關(guān)聯(lián),將未關(guān)聯(lián)的結(jié)果設(shè)置為0,以獲得所需的結(jié)果。代碼如下:

with t _ houras(select ' 00 ' asdhourunionallselect ' 01 ' asdhourunionallselect ' 02 ' asdhourunionallselect ' 03 ' asdhourunionallselect ' 04 ' asdhourunionallselect ' 05 ' ASD houriunionallselect ' 06 ' asdhourunionallselect ' 07 ' asdhouru

通過手動(dòng)構(gòu)造dt和dhour,用笛卡爾積產(chǎn)生了一個(gè)“序列”。而對于dhour的構(gòu)造,也可以采用笛卡爾積的方式,但需要注意限制范圍不大于23,代碼如下:

witht_houras(select&#3深圳生活網(wǎng)9;0'asidunionallselect'1'asidunionallselect'2'asid),f_houras(select'0'asidunionallselect'1'asidunionallselect'2'asidunionallselect'3'asidunionallselect'4'asidunionallselect'5'asidunionallselect'6'asidunionallselect'7'asidunionallselect'8'asidunionallselect'9'asid)selectconcat(a.id,b.id)hourfromt_houra,f_hourbwhereconcat(a.id,b.id)<='23'orderbyhour

以上我們都主要使用了笛卡爾積產(chǎn)生順序值的場景,類似的可以構(gòu)造從00~99的數(shù)字,構(gòu)造之后也可以根據(jù)實(shí)際需要加入新的限制條件。

注:例子來源于《SQL Cookbook》第6章,經(jīng)過自己的修改。

問題:考慮用SQL實(shí)現(xiàn):將表emp中name為KING的字符串顯示為4行,每行包含其中一個(gè)字符。

這里需要笛卡爾積配合字符串截取函數(shù)來實(shí)現(xiàn)。要實(shí)現(xiàn)逐一訪問字符串,需要有一個(gè)中間表,存儲(chǔ)序列值,類似于前面提到的序列。我們看下下面的代碼:

witht5as(select1asposunionallselect2asposunionallselect3asposunionallselect4asposunionallselect5aspos),empas(select'KING'asname)select*fromemp,t5

得到的結(jié)果如下圖所示:

考慮到字符串截取函數(shù)能夠按位置截取。正好可以用上生成的pos。代碼如下:

witht5as(select1asposunionallselect2asposunionallselect3asposunionallselect4asposunionallselect5aspos),empas(select'KING'asname)selectsubstr(name,pos,1)fromemp,t5wheret5.pos<=length(emp.name)

可以看到使用了pos,就能夠“循環(huán)”地截取字符串了。需要注意where里加上了循環(huán)跳出的條件,這也比較好理解:不能截取超過字符串長度的字符。

還可以按照需要調(diào)整遍歷時(shí)輸出的格式,如下面代碼和結(jié)果所示:

selectsubstr(name,pos)char_name1,substr(name,length(name)-pos+1)char_name1fromemp,t5wheret5.pos<=length(emp.name)

這個(gè)例子中我們利用笛卡爾積模擬循環(huán),對字符串進(jìn)行了遍歷。

本文首先學(xué)習(xí)了with as的用法,然后通過例子總結(jié)了兩個(gè)巧妙使用笛卡爾積的場景:生成序列和模擬循環(huán)。雖然在實(shí)際中可能用的不是很多,但也體現(xiàn)出了SQL的靈活性。生成序列可以更廣義的理解為:需要產(chǎn)生兩個(gè)表中字段的任意組合,這兩個(gè)字段可能是沒有實(shí)際聯(lián)系的??梢詤⒖枷旅骀溄又嘘P(guān)于每個(gè)班級血型的例子,核心思想也是這個(gè)。

https://blog.csdn.net/xiaolinyouni/article/details/6943337

實(shí)際中應(yīng)該有很多類似的場景。

而模擬循環(huán)是笛卡爾積結(jié)合了字符串截取函數(shù)實(shí)現(xiàn)的,本質(zhì)上還是“組合”。下次再遇到類似場景的時(shí)候,可以考慮下笛卡爾積能否實(shí)現(xiàn)。

以上就是笛卡爾積(SQL查詢中笛卡爾積的巧妙使用)這篇文章的一些介紹,網(wǎng)友如果對笛卡爾積(SQL查詢中笛卡爾積的巧妙使用)有不同看法,希望來共同探討進(jìn)步。

免責(zé)聲明:本文由用戶上傳,如有侵權(quán)請聯(lián)系刪除!