2015-05-02 78 views
1
driver [ dcode, dname ] 
route [ rcode, departure,arrival ] 
ride [ dcode, rcode ] 

SELECT dname FROM driver WHERE dcode IN (
    SELECT dcode FROM ride WHERE rcode IN (
     SELECT rcode FROM route WHERE departure = 'Barcelona' AND arrival = 'Madrid' 
    ) AND 
    rcode IN (
     SELECT rcode FROM route WHERE departure = 'Madrid' AND arrival= 'Barcelona' 
    ) 
); 

這是關於一個司機誰使兩個路線:馬德里巴塞羅那和巴塞羅那馬德里,但我的查詢不起作用。MySQL:double IN()語句

+0

您的查詢是否會導致錯誤或返回沒有結果?我假設有多條路線具有相同的應該返回的rcode。 – hines

回答

0

不應該說是

SELECT dname FROM driver WHERE dcode IN (
    SELECT dcode FROM ride WHERE rcode IN (
     SELECT rcode FROM route WHERE departure = 'Barcelona' AND arrival =  
'Madrid' 
    ) OR 
    rcode IN (
     SELECT rcode FROM route WHERE departure = 'Madrid' AND arrival= 'Barcelona' 
    ) 
); 

OR而不是AND ...?

+0

我認爲這取決於數據是如何構造的,因爲要求是驅動程序創建兩條路線,而不僅僅是兩條路線中的一條。 – hines

+0

@hines是的,但如果只有一條路線,馬德里巴塞羅那和「返回」缺失,您將不會得到任何結果或可能是錯誤,因爲列表爲空。 –

2

您的內部查詢(2nd lvl)不會返回任何結果,因爲可能不存在rcode,它可能在第一個子集(B-> M)AND在第二個(M-> B)中。請試試這個:

SELECT dname FROM driver WHERE dcode in 
(SELECT dcode 
FROM ride JOIN route 
ON (ride.rcode=route.rcode) 
WHERE route.departure = 'Barcelona' AND route.arrival = 'Madrid' 
) AND dcode in (
SELECT dcode 
FROM ride JOIN route 
ON (ride.rcode=route.rcode) 
WHERE route.departure = 'Madrid' AND route.arrival = 'Barcelona' 
) 
+0

只是一個小小的更正:在涉及'join'子句的語句中只有一個表中的條件應該在where子句中,而不在on子句中。這可能看起來像挑剔,但它使查詢更易於閱讀,因爲sql代碼更好地傳達了含義。 –

+0

感謝您的提示,Zohar,我申請了我的編輯......但它真的「只是可讀性」! (我發現自己經常「誤用」「在」條款作爲「where」條款......感覺就像一個問題的演變:) – xerx593

+1

我不知道它是否會以任何方式影響查詢的性能,但這可以通過比較與此特定更改相同的查詢的執行計劃,可以非常容易地進行測試。在任何情況下,代碼可讀性都不能掉以輕心。總是想想這個可憐的混蛋,從現在開始的18個月內,你必須對代碼進行維護工作。這個可憐的混蛋很有可能是你:-) –

0

我能想到的地方IN沒有返回結果它應該,是當有您的表NULL RCODE的唯一方案。嘗試使用下面的查詢

SELECT dname FROM driver WHERE dcode IN (
SELECT dcode FROM ride WHERE rcode IN (
    SELECT rcode FROM route WHERE departure = 'Barcelona' 
    AND arrival = 'Madrid' AND rcode IS NOT NULL 
) AND 
rcode IN (
    SELECT rcode FROM route WHERE departure = 'Madrid' 
    AND arrival= 'Barcelona' AND rcode IS NOT NULL 
) 
); 
2

where in是錯誤的做法,你要找的是什麼where exists

SELECT dname FROM driver WHERE exists 
    (select dcode from route inner join ride on route.rcode = ride.rcode 
    where departure = 'Barcelona' and arrival = 'Madrid' and ride.dcode = driver.dcode 
) 
    and exists 
    (select dcode from route inner join ride on route.rcode = ride.rcode 
    where departure = 'Madrid' and arrival = 'Barcelona' and ride.dcode = driver.dcode 
) 

或者,您也可以在所有沒有子查詢做到這一點:

select dname 
    from driver d 
    inner join ride r 
     on d.dcode = r.dcode 
    inner join route rr 
     on r.rcode = rr.rcode 
     and rr.departure = 'Barcelona' 
     and rr.arrival = 'Madrid' 
    inner join ride r2 
     on d.dcode = r.dcode 
    inner join route rr2 
     on r2.rcode = rr2.rcode 
     and rr2.departure = 'Madrid' 
     and rr2.arrival = 'Barcelona'; 

demo here

+0

我認爲「錯誤的方法」,不是「完整的真相」,但非常好(正確)的查詢和演示! (+1) – xerx593

+0

我會說在語義'in'是不正確的。 –

1

我覺得ap您正在採取的步驟是:

  1. 獲取dcode爲巴塞羅那到馬德里的路線司機。我們稱之爲Set1
  2. 獲取dcode司機從馬德里到巴塞羅那。我們稱之爲Set2
  3. 最後,得到了dname司機,其dcode在兩個SET1SET2

您的SET1查詢:

SELECT dcode FROM ride WHERE rcode IN (
    SELECT rcode FROM route WHERE departure = 'Barcelona' AND arrival = 'Madrid' 
) 

在同一行的查詢SET2是:

SELECT dcode FROM ride WHERE rcode IN (
    SELECT rcode FROM route WHERE departure = 'Madrid' AND arrival = 'Barcelona' 
) 

最後,你需要得到dcodeSet1 & inSet2。這將轉換爲查詢:

SELECT dname FROM driver WHERE 
dcode IN (
    SELECT dcode FROM ride WHERE rcode IN (
     SELECT rcode FROM route WHERE departure = 'Barcelona' AND arrival = 'Madrid' 
    ) 
) 
AND 
dcode IN (
    SELECT dcode FROM ride WHERE rcode IN (
     SELECT rcode FROM route WHERE departure = 'Madrid' AND arrival = 'Barcelona' 
    ) 
) 

在您的查詢,而不是兩套尋找dcode,你在兩組尋找rcode

改進建議:對於查詢得到dcode集合,您可以使用內部連接而不是使用嵌套查詢。例如:

SELECT dcode FROM ride INNER JOIN route ON ride.rcode = route.rcode 
WHERE departure = 'Barcelona' AND arrival = 'Madrid'