2008-10-20 64 views
79

交叉連接對兩組元組執行笛卡爾乘積。交叉加入有什麼用途?

SELECT * 
FROM Table1 
CROSS JOIN Table2 

哪種情況下渲染這樣的SQL操作特別有用?

+19

這個問題已經關閉,真的很傷心。我認爲它可能是社區Wiki的標誌,但說這不是建設性的是不公平的。 – 2016-02-09 03:15:31

+0

我同意。這回答了我的確切問題。 – Hades 2017-08-04 15:08:59

回答

71

如果你有,你想要完全填充,如大小和顏色信息的衣服特定物品的「網格」:

select 
    size, 
    color 
from 
    sizes CROSS JOIN colors 

也許你想包含一排中的每一分鐘的表某一天,你想用它來驗證程序已經執行的每一分鐘,所以你可能會跨越三個表:

select 
    hour, 
    minute 
from 
    hours CROSS JOIN minutes 

或者你有一組標準的報告規範的要應用到每月在這一年:

select 
    specId, 
    month 
from 
    reports CROSS JOIN months 

將這些視爲視圖的問題在於,在大多數情況下,您不需要完整的產品,特別是關於衣服。您可以將MINUS邏輯添加到查詢中以刪除某些不包含的組合,但可能會發現以其他方式填充表格並且不使用笛卡爾產品更容易。另外,您最終可能會嘗試交叉連接表,這些表的行數可能比您想象的還要多,或者您的WHERE子句部分或完全缺失。在這種情況下,您的DBA會立即通知您這一遺漏。通常他或她不會高興。

12

對於大多數數據庫查詢,您通常不需要完整的笛卡爾產品。關係數據庫的全部功能是,您可以應用您可能感興趣的任何限制,以避免從數據庫中提取不必要的行。

我想一個人爲的例子,你可能想那是,如果你有員工的表以及一個需要做的工作表,並希望看到一個員工都可以分配到一個工作。

7

生成測試數據。

1

想象一下,你有一個系列中,您要發出超過項目和日期(價格,可用性等)的特定組合查詢。您可以將項目和日期加載到單獨的臨時表中並讓您的查詢交叉連接表格。這可能比枚舉IN子句中的項目和日期的替代方法更爲方便,特別是因爲某些數據庫限制了IN子句中元素的數量。

9

好吧,這可能不會回答這個問題,但是,如果這是真的(我甚至不能確定那),這是歷史的一個有趣的一點。

在Oracle的早期階段,其中一位開發人員意識到他需要複製表中的每一行(這可能是一個事件表,並且他需要將其更改爲「開始事件」和「結束事件」) 。他意識到,如果他有一張只有兩排的桌子,他可以做一個交叉連接,只選擇前兩列中的列,並得到他需要的。所以他創造了一張簡單的桌子,他自然地稱之爲「DUAL」。

後來,他需要做一些事情,只能通過表格中的選擇來完成,即使動作本身與表格無關(也許他忘記了他的手錶並且想通過SELECT讀取時間SYSDATE FROM ...)他意識到他仍然有他的DUAL桌子躺着,並用它。過了一會兒,他厭倦了看到兩次打印的時間,所以他最終刪除了其中一行。

Oracle的其他人開始使用他的表,最終決定將其包含在標準的Oracle安裝中。

這就解釋了爲什麼一個只有一行意義的表有一個名字,意思是「兩個」。

3

採取類似於數字表的東西,它有10個數字0-9的行。您可以多次在該表上使用交叉連接,以獲得需要多行的結果,並將結果進行適當編號。這有很多用途。例如,您可以將它與datadd()函數結合使用,以獲取給定年份中每天的集合。

5

關鍵是「向我展示所有可能的組合」。我已經將這些與其他計算字段結合使用,然後對這些字段進行排序/過濾。

例如,假設您正在構建套利(交易)應用程序。您有賣家以一定的價格提供產品,並且買家要求產品付出代價。您對產品密鑰進行交叉連接(以匹配潛在買家和賣家),計算成本和價格之間的差價,然後對desc進行排序。在此給你(中間人)最有利可圖的交易執行。當然你幾乎總是會有其他的邊界過濾標準。