2015-10-31 140 views
0

我有表:SQL相關同桌的子查詢

Person(SSN, name, address) 
Car(license, year, model) 
Accident(license, accident-date, driver, damage-amount) 
Owns(SSN, license) 

問題問:

查找已參與了超過一個意外的所有汽車的牌照號碼(不返回DUPLICATES )。

答案之一是:

SELECT DISTINCT A1.license 
FROM Accident A1 
WHERE A1.license IN (SELECT A2.license 
        FROM Accident A2 
        WHERE A1.accident-date <> A2.accident-date) 

它從未將檢查A1.license = A2.license在相關子查詢。因此,據我瞭解,即使兩個元組擁有不同的許可證,子查詢也會檢查A1中的元組是否具有與A2中的元組不同的事件日期。所以這不應該是錯誤的?

編輯:它假定一輛汽車在一天中不能有多個事故。

+1

這個「答案」顯然是錯誤的,如果'Accident'中有多個日期,它將返回* all *行。正如你所說的那樣,缺少'AND A1.license = A2.license'。 – dnoeth

+0

哪種RDBMS適用於?請添加一個標籤來指定您是使用'mysql','postgresql','sql-server','oracle'還是'db2' - 或者其他的東西。 –

+0

這個問題沒有指定,但由於我的課是學習只是MySQL,我已經標記了mysql。 –

回答

1

其實IN運營商正在檢查許可證的平等。讓我們做一個測試。說Accidents表包含行:對外部查詢的每一行

License AccidentDate 
L1  20151001 
L1  20151020 
L2  20151025 

相關子查詢進行評估。想象一下遍歷行的遊標。對於row1A.LicenceL1。內部子查詢只檢查與20151001不同的日期,它會發現row2row3(L1, L3)。所以A.LicenceL1是在內部子查詢的結果集中,它將返回最終結果。所以做第二行。但不包括row3,因爲20151025之後的日期中沒有L2。所以查詢是正確的。

+0

爲什麼第3行不會從子查詢中返回?在子查詢中,我們從不檢查A1.license = A2.license。因此,子查詢會比較row3的日期和row1的日期,並且日期不同,因此它會返回,不是嗎? –

+1

不,子查詢將外部查詢當前行的日期與日期進行比較。 Where子句將消除IN謂詞評估爲false的所有行。現在想象一下,在外部查詢中,您位於row3的位置。 L2 20151025.內部子查詢呢?它會篩選日期與20151025之外的其他日期,並發現20151001和20151020,但都是L1,因此當您處於排名第3行時,您將獲得L2 IN(L1)。所以謂詞是錯誤的,第3行被刪除。 –

+1

用文字說出來:給我一些意外的行,其中許可證編號可以在一組許可證號碼中找到,其中的日期與我的崩潰日期不同。如果我能找到與其他日期相同的一組,則意味着該車處於多次碰撞事故中。 –