2010-07-07 7 views
6

Üç tablo var, 'A', 'B' ve 'C'. 'A' ve 'B' ile ilgili bir sorgum var, ancak bir veya daha fazla (kaç tane umurumda değil) 'C' olduğunu ve 'A'ya' yabancı anahtarlı olup olmadığını söyleyen bir alan eklemek istiyorum.Bir sol birleşim herhangi bir satır döndürürse '1' değerini döndürmenin daha iyi bir yolu?

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; 

Biraz verimsiz görünüyor, gerçekten istediğim tüm olup olmadığını nerede olduğunu sayıyorum çünkü ve ayrıca GROUP BY tüm bu alanları listelemek zorunda hem çünkü: Burada

Elimde ne var en az bir eşleşme ya da değil. Bu geliştirilebilir mi? haklısınız olsa bu durumda);

+1

Var. Sayımı sıralamak ve tablolamak maliyetlidir, ancak belki de daha maliyetli olması, DB'nin bu sayımı elde etmek için Çizelge C'deki TÜM satırlardan geçmesi gerektiğidir. EXISTS çözümü ile ilk eşleşen satırı bulur bulmaz aramayı durdurabilir. –

+0

İyi bir açıklama, @ Tom. –

cevap

13

kullanımı ... yerine alt sorgu ile bir sorgu verimsiz yapmaz sütun adları bir sürü yazmanız gerekiyordu diye

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

için +1 var :-) – corsiKa

+0

Mükemmel. EXPLAIN PLAN, bunun da daha iyi olduğunu söylüyor. Kabul edene kadar 3 dakika. –

+1

@Paul Tomblin: Çünkü kriterler için ilk başarılı eşleşme bulunduğunda EXISTS doğru olarak dönecektir - eşleşen tüm kriterleri kontrol etmek için EXISTS'e gerek yoktur. –

İlgili konular