2017-09-09 49 views
1

當我運行下面的腳本時,即使使用distinct,我也不斷得到重複結果。Oracle SQL Plus中的重複結果

select distinct 
a.SDT, a.fNo, b.IDType, b.pNo, b.pfName, b.plName, b.PDoB, b.Street, b.City, c.Phone 
from Scheduled_Flight a, Passenger b, pass_Phone c 
where fNo = '0000021' 
and 
a.SDT = '08-sep-2017 17:30'; 

Duplicates in Oracle 我是新來的SQL和任何幫助,將不勝感激爲解決這一問題。

+1

*從不*在'FROM'子句中使用逗號。 *總是*使用正確的,明確的'JOIN'語法。 –

+1

如果沒有適合您的連接條件,您基本上會創建一個交叉連接,從而生成[笛卡爾產品](https://en.wikipedia.org/wiki/Cartesian_product)。看看[其他連接](http://docs.oracle.com/javadb/10.6.2.1/ref/rrefsqlj29840.html)。 – GolezTrol

+0

請閱讀http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557和接受的答案 –

回答

2

「我不斷收到重複的結果,使用不同的甚至當」

你沒有得到結果集中的重複。相反,你有一個笛卡爾產品,它是一個航班,三個乘客和三個電話號碼的組合。集合中的每條記錄都是唯一的,因此distinct不會有任何影響。

問題是您在from子句中沒有加入條件。在passenger上應該有一列,它是flight上的外鍵,pass_phone上的一列是passenger上的外鍵。

這很容易解決:你只需要加入表格。假設你的數據模型是一致的,您的查詢應該是這樣的(並且你不需要DISTINCT):

select a.SDT, a.fNo, b.IDType, b.pNo, b.pfName, b.plName, b.PDoB, b.Street, b.City,c.Phone 
from Scheduled_Flight a 
     join Passenger b on b.fNo = a.fNo 
     join pass_Phone c on c.pNo = b.bNo 
where a.fNo = '0000021' 
and a.SDT = '08-sep-2017 17:30'; 

然而,我注意到,在您的查詢的版本,你沒有前綴fNo。這讓我覺得你沒有在passenger上有這個名字的列(否則查詢將在ORA-00918: column ambiguously defined上失敗)。所以,外鍵列的命名不同,或者你沒有得到它們。


「是否有可能沒有時間僅指定的日期?」

是的。使用ANSI date literal,例如date '2017-09-08'

「是否可以只指定日期而沒有時間仍然產生數據庫結果?」

這取決於數據的存儲方式。 Oracle日期與時間元素一起存儲。如果沒有指定時間(或時間元素被截斷),則時間元素默認爲午夜。這通常會吸引初學者,例如,因爲僞列sysdate返回當前日期時間,而不僅僅是當前日期。

所以,如果你知道的日期都存儲在你的表沒有時間元素,你可以這樣做:

where a.sdt = date '2017-09-08' 

但是,如果你不知道,你可以截斷...

where trunc(a.sdt) = date '2017-09-08' 

或測試的範圍

where a.sdt >= date '2017-09-08' 
and a.sdt < date '2017-09-09' 

「爲什麼下面的代碼仍然產生重複的結果?

select distinct r.sNo, r.tCode, s.fNo, s.SDT 
from Airplane r, Scheduled_Flight s 
where SDT >= SYSDATE -1; 

釷e飛機屬性不能有s.SDT屬性。「

沒有看到輸出我不能確定,但​​我敢打賭,這個查詢不會產生重複記錄。你有什麼是一個產品結合所有您的AIRPLANE記錄與您的FLIGHT記錄匹配sdt過濾器。

這是另一個數據建模問題。當然,飛機沒有飛行時間:一架飛機進行多次飛行。但是,將飛機分配到飛機上是非常合理的。事實上,這對確保你沒有更多的航班比你有飛機飛行是至關重要的,而且一架飛機不打算從倫敦起飛前往馬德里,那時它計劃在中途停飛。香港。

您確實應該使用ANSI 92語法,正如我在回答您之前發佈的代碼時所展示的那樣。顯式連接不僅使它更容易理解查詢,而且可以防止這樣的錯誤。您顯然沒有任何候選列來進行連接的事實立即突出顯示了數據模型中的缺陷。

select distinct r.sNo, r.tCode, s.fNo, s.SDT 
from Airplane r 
    INNER JOIN Scheduled_Flight s ON ???? 
where SDT >= SYSDATE -1; 
+0

是否可以只指定日期而沒有時間仍然從數據庫產生結果? – Dave

+0

如此不同不適用於笛卡爾連接?那是錯的。 – miracle173

+0

@ miracle173 - 不確定你想要做什麼。 'distinct'保證結果集包含一組唯一的行。笛卡爾乘積是一個結果集,其中每行*組合*包含一行。笛卡爾產品中的每一行都可能是獨一無二的,如果「獨特」不會產生任何影響。 – APC

1

我不認爲這是重複的,如果比較每行每列的任何行,每行的唯一標識,因爲你正在做笛卡爾乘積你越來越多條記錄。但每一行都是彼此唯一的。