2010-07-07 83 views
6

我有三張桌子,'A','B'和'C'。我對'A'和'B'有疑問,但我想添加一個字段,告訴我是否存在一個或多個(我不在乎多少)'''外鍵'A'的'C'。如果左連接返回任何行,返回'1'的更好方法是?

這是我有:

SELECT A.A_id, A.col_2, col_3, B.col_2, A.col_4 
      count(C.id) as C_count 
FROM  A 
JOIN  B ON (A.B_id = B.B_id) 
LEFT JOIN C ON (A.A_id = C.A_id) 
WHERE  A.A_id = ? 
GROUP BY A.A_id, A.col_2, col_3, B.col_2, A.col_4 
ORDER BY CASE WHEN A.col_2 = ? 
       THEN 0 
       ELSE 1 
      END, col_3; 

這似乎有點低效率的,一方面是因爲我必須列出在GROUP BY以及所有這些領域,因爲我指望在那裏我真正想要的是,是否有至少有一場比賽或沒有。這可以改善嗎?

+1

只是因爲你必須輸入大量的列名不進行查詢效率低;)在這種情況下,雖然,你是正確的。對計數進行排序和列表成本很高,但是可能更昂貴的是數據庫必須通過表C中的所有行來計算。只要EXISTS解決方案找到第一個匹配的行,就可以停止查找。 – 2010-07-07 15:23:12

+0

好解釋,@湯姆。 – 2010-07-07 15:30:03

回答

13

使用exists使用子查詢,而不是...

Select A.A_id, A.col_2, col_3, 
    B.col_2, A.col_4, 
    Case When Exists (Select * From C 
         Where A_id = A.A_id) 
     Then 1 Else 0 End As C_Exists 
From A Join B 
    On (A.B_id = B.B_id) 
Where A.A_id = ?  
Order By Case When A.col_2 = ? 
      Then 0 Else 1 End, col_3; 
+0

+1爲存在:-) – corsiKa 2010-07-07 15:19:54

+0

優秀。解釋計劃說它也更好。 3分鐘,直到我可以接受它。 – 2010-07-07 15:23:46

+1

@Paul Tomblin:這是因爲只要找到與標準的第一次成功匹配,EXISTS就會返回true - 因此EXISTS不需要檢查所有匹配條件。 – 2010-07-07 15:29:05